Why do two enumeration enumeration variables have the same integer value?

I know that if I determined the day of the week of listing as follows:

enum weekday { MON, TUE, WED, THU, FRI, }; 

Then MON will default to 0, and TUE - 1, WED - 2 ...

But if I define it like this:

 enum weekday { MON, TUE = 0, WED, THU, FRI, }; 

Then both MON and TUE will get the value 0.

How will the system differentiate MON and TUE internally? I mean, if I declare something like this:

 enum weekday today = 0; 

Then is there today MON or TUE ? Or, philosophically speaking, both?

+30
c enums
Jul 10 '12 at 11:37
source share
5 answers

C enumerations are "really" integers - not only because they are implemented in this way, but because the standard defines the types of enumerations in order to have integer values. So the value of today "truly" 0. All that happened is that you created two different names for the value 0.

I believe that the answer is today MON or TUE is yes; -)

The language does not stop you, because it is sometimes useful to list several names for the same value. For example:

 enum compression_method { COMP_NONE = 0, COMP_LOW = 1, COMP_HIGH = 2, COMP_BEST = 2, COMP_FASTEST = 0, }; 
+49
Jul 10 2018-12-12T00:
source share

Why do two different enumeration constants have the same integer value?

Since this is explicitly permitted by the standard project N1265 C99 in 6.7.2.2/3 "Listing Qualifiers":

Using counters with = can lead to enumeration constants with values ​​that duplicate other values ​​in the same enumeration.

How will the system differentiate MON and TUE internally?

I think this is not possible because they are compile time constants (6.6 / 6 "Constant Expressions"). As a result, they:

  • cannot be changed to differ after compilation

  • don't have an address to tell them apart: The storage location of the enum value in C

    Compile-time constants do not need any address, because addresses are useless for things that you cannot change.

GCC simply replaces the use of enumeration members with immediate values ​​in the assembly at compile time. Consider:

 #include <stdio.h> enum E { E0 = 0x1234, E1 = 0x1234 }; int i = 0x5678; int main() { printf("%d\n", E0); printf("%d\n", E1); printf("%d\n", i); return 0; } 

Compile and decompile with GCC 4.8 x86_64:

 gcc -c -g -O0 -std=c89 main.c objdump -Sr main.o 

The output contains:

  printf("%d\n", E0); 4: be 34 12 00 00 mov $0x1234,%esi ... printf("%d\n", E1); 18: be 34 12 00 00 mov $0x1234,%esi ... printf("%d\n", i); 2c: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 32 <main+0x32> 2e: R_X86_64_PC32 i-0x4 32: 89 c6 mov %eax,%esi 

So we see that:

  • enumeration members are used as direct $0x1234 , so it’s impossible to know where they came from
  • the variable i , however, comes from memory 0x0(%rip) (for moving), so the two variables can be differentiated by address
+15
Jun 18 '15 at 13:15
source share

To complement the other answers, I will give you a practical example of how using the same value for different enums in a given enum is very useful:

 enum slots_t { SLOT_FIRST = 0, SLOT_LEFTARM = SLOT_FIRST, SLOT_RIGHTARM = 1, SLOT_TORSO = 2, SLOT_LEFTLEG = 3, SLOT_RIGHTLEG = 4, SLOT_LAST = SLOT_RIGHTLEG }; 

Then you can do in your code:

 for (int i = SLOT_FIRST; i <= SLOT_LAST; ++i) { } 
+8
Jun 18 '15 at 17:59 on
source share

It is as philosophical (or not) as

 #define ZILCH 0 #define NADA 0 

There are many uses when it makes sense to have different names in the same amount.

+4
Jun 16 '14 at 11:02
source share

The name of the enumeration constant is used to assign a value, not the actual value itself. If you assign the value 0 today, the output value will be 0. And yes, both MON and TUE will have the value 0, and the remaining ones will be assigned the value WED = 1 THU = 2, etc.

+2
Jul 10 2018-12-12T00:
source share



All Articles