C++ - enum vs. const vs. #define

2019-01-03 10:49发布

At the end of the article here: http://www.learncpp.com/cpp-tutorial/45-enumerated-types/, it mentions the following:

Finally, as with constant variables, enumerated types show up in the debugger, making them more useful than #defined values in this regard.

How is the bold sentence above achieved?

Thanks.

7条回答
对你真心纯属浪费
2楼-- · 2019-01-03 11:10

Consider this code,

#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;
}

Obviously each multiplication results in compilation-error, but see how the GCC generates the messages for each multiplication error:

prog.cpp:19: error: no match for ‘operator*’ in ‘eWidth * s’
prog.cpp:20: error: no match for ‘operator*’ in ‘300 * s’
prog.cpp:21: error: no match for ‘operator*’ in ‘Width * s’

In the error message, you don't see the macro WIDTH which you've #defined, right? That is because by the time GCC makes any attempt to compile the line corresponds to second error, it doesn't see WIDTH, all it sees only 300, as before GCC compiles the line, preprocessor has already replaced WIDTH with 300. On the other hand, there is no any such thing happens with enum eWidth and const Width.

See the error yourself here : http://www.ideone.com/naZ3P


Also, read Item 2 : Prefer consts, enums, and inlines to #defines from Effective C++ by Scott Meyers.

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-03 11:10

The compiler stores enum information in the binary when the program is compiled with certain options.

When a variable is of a enum type, a debugger can show the enum name. This is best shown with an example:

enum E {
    ONE_E = 1,
};

int main(void)
{
    enum E e = 1;

    return 0;
}

If you compile that with gcc -g you can try out the following in 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) 

If you used a define, you would not have a proper type to give e, and would have to use an integer. In that case, the compiler would print 1 instead of ONE_E.

The -g flag asks gdb to add debugging information to the binary. You can even see that it is there by issuing:

xxd test | grep ONE_E

I don't think that this will work in all architectures, though.

查看更多
孤傲高冷的网名
4楼-- · 2019-01-03 11:18

I am answering too late but i feel i can add something - enum vs. const vs. #define

enum -

  1. Does not require assining values (if just want to have sequential values 0, 1, 2..) whereas in case of #defines you manually need to manage values which could cause human error sometime
  2. It works just as variable to during online debugging the value of enum can be watched in watch window
  3. You can have a variable of enum type to which you can assign an enum

    typedef enum numbers { DFAULT, CASE_TRUE, CASE_OTHER, };

    int main(void) { numbers number = CASE_TRUE; }

const -

  1. It is constant stored in read only area of memory but can be accessed using address which is not possible in case of #define
    1. You have type check in your hand if you use const rather than #define
  2. defines are pre-processing directive but const is compile time for example

    const char *name = "vikas";

You can access the name and use its base address to read the such as vikas[3] to read 'a' etc.

#defines - are dumb preprocessor directives which does textual replacement

查看更多
混吃等死
5楼-- · 2019-01-03 11:23

At least for Visual Studio 2008 which I currently have at hand, this sentence is correct. If you have

#define X 3
enum MyEnum
{
    MyX = 3
};

int main(int argc, char* argv[])
{
    int i = X;
    int j = (int)MyX;
    return 0;
}

and you set a breakpont in main, you can hover your mouse over "MyX" and see that it evaluates to 3. You do not see anything useful if you hover over X.

But this is not a language property but rather IDE behavior. Next versions might do it differently, as well as others IDEs. So just check it out for your IDE to see if this sentence applies in your case.

查看更多
Juvenile、少年°
6楼-- · 2019-01-03 11:25

Check the following article, nice summary http://www.queryhome.com/26340/define-vs-enum-vs-constant

查看更多
劳资没心,怎么记你
7楼-- · 2019-01-03 11:28

enum is compile time constant with debug info with no storage allocation.

const is allocated with a storage, depending on whether it is optimised away by the compiler with constant propagation.

#define has no storage allocation.

查看更多
登录 后发表回答