6

Recently, in this question I saw an enum used to define a single value. eg:

enum { BITS_PER_WORD = 32 };

Instead of:

#define BITS_PER_WORD 32

Assuming more members won't be added later, what - if any, are the advantages of doing this? (or is this more a a question of personal taste )

Said differently, if I have existing code using one-off int defines, is there any good reason to change these around for one-off enums shown above?

Out of curiosity I compared GCC's optimized assembler output for some non-trivial code and the result was unchanged betweem enums/defines.

Community
  • 1
  • 1
ideasman42
  • 42,413
  • 44
  • 197
  • 320
  • The compiler sees `BITS_PER_WORD` and equates it to 32 (unless something shadows that) in the first case. It sees 32 in the second. – chris Jul 29 '14 at 14:30
  • possible duplicate of [What makes a better constant in C, a macro or an enum?](http://stackoverflow.com/questions/17125505/what-makes-a-better-constant-in-c-a-macro-or-an-enum) – Eitan T Jul 29 '14 at 14:51
  • @Eitan T, its close but dont think its a duplicate, mainly because Im asking about single values and not which is better. But for specific language characteristics that make an enum less error prone (for example). – ideasman42 Jul 29 '14 at 14:54
  • Well, I'm not sure this slight difference justifies a separate question (your inquiry can be done by means of a comment in the broader question or in one of its answers). As you can see, the answers provide no new information in particular. – Eitan T Jul 29 '14 at 14:59
  • Added clarification (end of question) which I think differentiates it a bit from the general defines vs enum question. – ideasman42 Jul 29 '14 at 15:03

2 Answers2

9

Enumeration constants have several advantages:

  • They're scoped and don't expand in contexts where they shouldn't (as pointed out by mafso).
  • Most debuggers are aware of them and can use them in expressions written in the debugger.

Macros have several different advantages:

  • They can be use in preprocessor conditionals (#if BITS_PER_WORD == 32 won't work if BITS_PER_WORD is an enumeration constant).
  • They can have arbitrary types (also covered in mafso's answer).
  • They can be removed (#undef) when no longer needed.
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 4
    It should be noted that in the Standard all named constants are created using macros (and for some of them it is mandatory as they have types different than `int`). `true` and `false` `int` values from `stdbool.h` are explicitly macros and I think the reason is to allow the programmer to redefine them (using `#undef`). – ouah Jul 29 '14 at 15:46
  • 1
    @ouah: Good points. Actually I think the ability to use them in the preprocessor is one of the most important parts since they're not only required to be macros, but also ones that give the right results when used in the preprocessor (e.g. `(char)+256` would be a way of writing zero on most implementations, but it would have the wrong value at the preprocessor level). – R.. GitHub STOP HELPING ICE Jul 29 '14 at 16:43
5

An advantage is that enums are scoped and you can define the enum inside a block. A macro would also expand for e.g.:

foo.BITS_PER_WORD;

or even

void foo(int BITS_PER_WORD) { /* ... */ }

An advantage of a macro is, that you can define it to non-int values.

mafso
  • 5,433
  • 2
  • 19
  • 40
  • 2
    FYI, scope is not an issue for a `#define`. It applies to the code following it, so if you want to limit its scope, just `#undef` it. – Eitan T Jul 29 '14 at 14:55
  • 2
    @EitanT: It **can** be a problem if other macros that you're still using depend on the macro you're about to undefine, and subsequently stop working. It can also be a maintenance burden since, after including `"foo.h"`, you have to know what to `#undef` to keep it from breaking your code, and that set of macros keeps changing (or, if it's a system header that does not respect the standard namespace rules, changes from system to system...). – R.. GitHub STOP HELPING ICE Jul 29 '14 at 16:49
  • I didn't say it wouldn't be a maintenance burden. I've just pointed out that you _can_ overcome the limitation of scope with macros. – Eitan T Jul 30 '14 at 07:35