7

Is it possible to get a value of an enum member at compile time?

In fact, I want to be able to do something like this:

enum { 
   FOO_FIRST = -1,
   FOO_A,
   FOO_B,
   FOO_C,
   FOO_LAST
};

#if FOO_LAST > 10
//...
#else
//..
#endif

I know that the cpp don't know about variables, bad syntax, etc; only things that start with a #(right)? but members of an enum has fixed-size and cannot be changed just like 10 (constant integer) value and the compiler know its size and values. so, Is there no any possibility to do such comparison (as I did above)? Could I use gcc-extensions?

I don't wish to rewrite all my enumerations by using #defines and don't take my time doing some macros change.

halfer
  • 19,824
  • 17
  • 99
  • 186
Jack
  • 16,276
  • 55
  • 159
  • 284
  • 1
    What are you trying to do inside your `#if` blocks? – ecatmur Nov 02 '12 at 16:03
  • can't think of any actual use case where this is useful.. – Karoly Horvath Nov 02 '12 at 16:05
  • [enum and #define](http://stackoverflow.com/questions/136946/difference-between-enum-and-define-statements) – जलजनक Nov 02 '12 at 16:06
  • One-of is the following: if the last enum member is greater than `7`, I need to put a lot of if() conditions and loops, otherwise just: `if(foo) { exp1; }` – Jack Nov 02 '12 at 16:07
  • why? do you need the number of bits it uses, or what? if you don't explain the "why", it's still just a weird requirement and not an actual useful case – Karoly Horvath Nov 02 '12 at 16:08
  • because this value is variable. Don't depends me how long it is. For example, the current value the enumeration has 7-members in the next time that I will compile it, I don't know. If it's possible, just would less time to edit source code. if #enum_member_x > 10 it's possible, some if() will help me a lot. It's the question. I asked it because I want no rewrite back my enum by using defines. But as it's not possible(until I see now), I'II do it. (sorry for my ba english, not a native speaker) – Jack Nov 02 '12 at 16:14

2 Answers2

7

Just use if. Enums can be evaluated at compile time just fine. The compiler will optimize the impossible branches out:

if (FOO_LAST > 10) {
    // A
} else {
    // B
}

The compiler knows which of the two branches (A and B) cannot be reached, so it can eliminate the if completely.

Note however, that you should only use the enumerators directly. For example, in this:

int num = FOO_LAST;
if (num > 10) {
    // A
} else {
    // B
}

GCC will keep the if comparison.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • Very nice. I'II try it. Do you have a link with such optimization details? (we are talking on gcc?) – Jack Nov 02 '12 at 16:17
  • 1
    See this to get an idea: http://stackoverflow.com/questions/11281471/disable-if0-elimination-in-gcc You don't even have to enable the optimizer to get this behavior. Compile an example program with `-O2 -S` to get the assembly file. You'll see that there's no branching. – Nikos C. Nov 02 '12 at 16:21
  • I'm sorry "we are" must be "are we" :) – Jack Nov 02 '12 at 16:29
  • I forgot the case where you don't use the enumerators directly. I updated the answer. – Nikos C. Nov 02 '12 at 16:37
  • both gcc and clang remove the branch, even with `int num = LAST`. [See here](https://godbolt.org/g/7ox1Vn) – bolov Apr 20 '16 at 15:37
3

#ifdef is interpreted by the preprocessor and not by the compiler. The pre-processor does not know anything about the enums's values. So this is not a way to go.

alk
  • 69,737
  • 10
  • 105
  • 255