*Updated the post inspired by Nemo's great comments.
enum MY_ENUM{ MY_OK = 0, MY_NOT_OK }; void foo() { int i = -1; enum My_ENUM my_enum = MY_OK; if( i < my_enum) printf("I am OK!\n"); else printf("I am NOT OK!\n"); }
For the above example, we will see "I am NOT OK!". Why, the reason is in this example my_enum is regarded as unsigned int. Therefore, it will be converted into unsigned before the comparison. After the conversion, it will always be non-negative so the if will take the else branch. But what about this code snippet (just a little bit modification):
enum MY_ENUM{ MY_OK = 0, MY_NOT_OK }; void foo() { int i = -1; enum My_ENUM my_enum = MY_OK; if( i < MY_OK) printf("I am OK!\n"); else printf("I am NOT OK!\n"); }
It will print "I am OK!" instead. The reason is in this example MY_OK is regarded as int.
Why we will see results like this? It is kind of confusing. To find out the things under-hood, we need to look at the C standard. There are several sections related to our problem.
- Section 6.4.4.3 says enumerators have type int.
- Section 6.7.2.2/4 states that the enumeration type has a compatible type capable of representing the values of all enumerator members.
- Section 6.7.2.2/2 suggests that an enumerator initialized with a constant expressionthat falls outside the range of an int has unspecified or undefined behavior.
Then what if you want enumeration type to be int? Just follow Section 6.7.2.2/4 and have the enumeration defined as follow:
since we only need to represent -1,0 and 1 here, the enumeration type needs to be int.
We should be careful about Section 6.7.2.2/2. Since it suggests if we define something as follow, the behavior will be unspecified.
enum MY_ENUM{ MY_NEG = -1 MY_OK = 0, MY_NOT_OK };
since we only need to represent -1,0 and 1 here, the enumeration type needs to be int.
We should be careful about Section 6.7.2.2/2. Since it suggests if we define something as follow, the behavior will be unspecified.
enum MY_ENUM{ MY_NEG = -1 MY_OK = 0, MY_BIG = 0x80000000 };0x80000000 can't be represented in a 32bit int. Though in gcc, the enumeration type is still int here, we cannot expect a uniform behavior on other compilers.