在这篇文章的最后:http://www.learncpp.com/cpp-tutorial/45-enumerated-types/,它提到了以下内容:
最后,与常量变量一样,枚举类型显示在调试器中,使它们在这方面比#defined值更有用。
上面的粗体句子是如何实现的?
感谢。
答案 0 :(得分:29)
考虑这段代码,
#define WIDTH 300
enum econst
{
eWidth=300
};
const int Width=300;
struct sample{};
int main()
{
sample s;
int x = eWidth * s; //error 1
int y = WIDTH * s; //error 2
int z = Width * s; //error 3
return 0;
}
显然,每次乘法都会导致编译错误,但是看看GCC如何为每个乘法错误生成消息:
prog.cpp:19:错误:不匹配 'eWidth * s'中的'operator *' prog.cpp:20:错误:不匹配 '300 * s'中的'operator *' prog.cpp:21:错误:不匹配 'Width * s'中的'operator *'
在错误消息中,您没有看到WIDTH
的宏#defined
,对吧?这是因为当GCC使编译该行的任何尝试都对应于第二个错误时,它看不到WIDTH
,它只看到300,就像之前GCC编译该行一样,预处理器已经已经< / strong>用300替换WIDTH
。另一方面, enum eWidth
和 const {{1}没有任何此类事情发生}}
请在此处查看错误:http://www.ideone.com/naZ3P
此外,请阅读Scott Meyers的 Effective C ++ 中的Width
。
答案 1 :(得分:14)
enum
是编译时间常量,带有调试信息,没有存储分配。
const
分配了一个存储,具体取决于编译器是否通过常量传播对其进行了优化。
#define
没有存储空间分配。
答案 2 :(得分:6)
#define
值被预处理器替换为它们被声明为的值,因此在调试器中,它只能看到值,而不是#defined名称,例如如果您有#define NUMBER_OF_CATS 10,则在调试器中您只会看到10个(因为预处理器已将代码中的每个NUMBER_OF_CATS个实例替换为10个。
枚举类型本身就是一个类型,值是这种类型的常量实例,因此预处理器将其单独放置,您将在调试器中看到该值的符号描述。
答案 3 :(得分:3)
当使用某些选项编译程序时,编译器将枚举信息存储在二进制文件中。
当变量是枚举类型时,调试器可以显示枚举名称。最好用一个例子显示:
enum E {
ONE_E = 1,
};
int main(void)
{
enum E e = 1;
return 0;
}
如果您使用gcc -g
进行编译,可以在gdb
中试用以下内容:
Reading symbols from test...done.
(gdb) b main
Breakpoint 1 at 0x804839a: file test.c, line 8.
(gdb) run
Starting program: test
Breakpoint 1, main () at test.c:7
7 enum E e = 1;
(gdb) next
9 return 0;
(gdb) print e
$1 = ONE_E
(gdb)
如果你使用了一个定义,你将没有一个合适的类型来提供e
,并且必须使用一个整数。在这种情况下,编译器将打印1
而不是ONE_E
。
-g
标志要求gdb将调试信息添加到二进制文件中。你甚至可以通过发出:
xxd test | grep ONE_E
但我认为这不适用于所有架构。
答案 4 :(得分:0)
至少对于我目前手边的Visual Studio 2008,这句话是正确的。如果你有
#define X 3
enum MyEnum
{
MyX = 3
};
int main(int argc, char* argv[])
{
int i = X;
int j = (int)MyX;
return 0;
}
并且您在main
设置了一个breakpont,您可以将鼠标悬停在“MyX”上,并看到它的评估结果为3.如果将鼠标悬停在X上,则看不到任何有用的内容。
但这不是语言属性,而是IDE行为。下一版本可能会以不同的方式执行,以及其他IDE。因此,只需检查一下您的IDE,看看这句话是否适用于您的情况。
答案 5 :(得分:0)
我回答太晚但我觉得我可以添加一些东西 - enum vs. const vs. #define
枚举 -
您可以使用枚举类型的变量来指定枚举
typedef枚举数字 { DFAULT, CASE_TRUE, CASE_OTHER, };
int main(void) { numbers number = CASE_TRUE; }
const -
定义是预处理指令,但const是编译时 例如
const char * name =“vikas”;
您可以访问该名称并使用其基地址来阅读诸如vikas [3]以阅读'a'等。
#defines - 是愚蠢的预处理程序指令,它进行文本替换
答案 6 :(得分:0)