Maybe I can’t say anything that Kate Thompson hasn’t told you yet.
Anyway, I will do my best.
1. Values in the range of int
In ISO C99, I see in section 6.7.2.2 , paragraphs 2 and 3, the following statements:
(2) An expression defining the value of an enumeration constant must be an integer constant expression that has a value represented as int.
If you write enum T { X = (expr) } VAR , then expr is an integer in the range int , which includes at least the range -32767 .. +32767, as you can read in 5.2.4.2.1 .
Of course, paragraph (2) does not impose any restrictions on the type of identifier X.
2. Enumeration identifiers are of type int
In paragraph 3 we can read this line:
(3a) Identifiers in the list of enumerators are declared as constants of type int and can appear where it is allowed.
This is a restriction on the type of identifier. Now X is of type int .
3. Discussion of meanings
In addition, the standard says:
(3b) Enumerator c = defines its enumeration constant as the value of a constant expression.
But this proposal is now limited to (2) and (3a) .
So my interpretation of the C99 standard is this: If you write
enum T { X = INT_MAX, BIGG}
then BIGG is of type int (according to (3a) ).
As Kate Thompson pointed out, the value (= "enumerator constant?") Of BIGG does not come from an expression representing a value outside the range (for int ). Its value (in the mathematical sense) is equal to X + 1, since the following rule applies:
(3c) Each subsequent enumerator with no = defines its counting constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant.
There is no rule in the standard (on integer arithmetic) that defines the behavior of the compiler in this case. Thus, it falls into the implementation defined class ...
However, if the compiler takes this value out of range, I believe that the (mathematical) X + 1 will be converted to a value in the int range.
But the supposed behavior in (3b) is like the expression C (X + 1) == BIGG is always True . If I'm right, then I agree with Keith, and the compiler must reject the out-of- range error declaration.
4. The whole type of enumerated types
We can read this even more:
(4a) Each enumerated type must be compatible with char, a signed integer type, or an unsigned integer type.
The enum T declaration defines a new integer type .
This type is not necessarily related to the type of the expression expr , nor to the type of the counter X
This is just a different type for another thing: the integer type associated with the enum T type that we define.
(This type will be assigned to the variable VAR_T ).
An implementation may decide which type of integer is more suitable.
If expressions (e.g. expr ) have very small values, as this almost always happens, then the compiler can decide that T is of type char , for example.
If for some reason a long long is required then type T will be long long , etc.
However, this does not change the restrictions on int , which should be followed by the expression expr and the enumerator X They are int .
The only rule that binds the types expr and T :
(4b) The choice of type is determined by the implementation, but must be able to display the values of all members of the enumeration.
Thus, if you have enum T { X = 0, Y = 5, Z = 9 } , then the type T can be char .
(The situation is similar to the fact that a character constant, such as 'c' , which is always of type int , is passed to the variable char : char c = 'c'; although 'c' is int , its value corresponds to the range of char ).
On the other hand, if you have enum T { X = 20202, Y = -3 } , the compiler cannot select char for T It seems that int is an ideal type for T (as for any enum type), but the compiler can choose any other integer type for T whose range contains values 20202 and -3.
If no value is negative, then the compiler can select the unsigned integer type.
5. Summary
Thus, we can say that:
The expression (NN * 3) + 1 is int .
The expression (Z + 1) is int .
If the compiler defines T as char ,
then the expression ((evar = Z), ++evar) is char .