问题
enum Some_Flag {
SOME_FLAG_A = 0x00000000u,
SOME_FLAG_B = 0x00000001u,
SOME_FLAG_C = 0x00000002u,
/* ... */
SOME_FLAG_Z = 0x80000000u,
};
uint32_t a;
a = SOME_FLAG_Z;
Assuming 32 bit integers... Is this valid in C?
The standard seems ambiguous to me.
EDIT:
Quoting the standard:
6.4.4.3 Enumeration constants
Semantics
2 An identifier declared as an enumeration constant has type int. Forward references: enumeration specifiers (6.7.2.2).
6.7.2.2 Enumeration specifiers
Constraints
2 The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
Semantics
3 The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.127) An enumerator with = defines its enumeration constant as the value of the constant expression. If the first enumerator has no =, the value of its enumeration constant is 0. Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant. (The use of enumerators with = may produce enumeration constants with values that duplicate other values in the same enumeration.) The enumerators of an enumeration are also known as its members.
4 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,128) but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.
C11 draft
The constraints seem to clearly indicate that an enum is an int, but then 6.7.2.2_4 seems to allow unsigned ints ¿?
回答1:
Your code is not valid:
C90 (6.5.2.2, Enumeration specifiers):
Constraints
The expression that defines the value of an enumeration constant shall be an integral constant expression that has a value representable as an
int
.
C99 (and unchanged in the C11 draft) (6.7.2.2, Enumeration specifiers):
Constraints
- The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an
int
.
Your values exceed the range of a 32-bit int
, so this is an error (and a diagnostic is required).
Note that this is strictly about the "initializers" of the enum constants. For example, if we have
enum foo { BAR = 42u };
then this constraint says that the value 42u
must be able to fit in an int
(which it does; it's just an unsigned 42 and 42 fits in an int
).
The type of BAR
itself is int
(surprisingly enough, not enum foo
).
But if you declare a variable of type enum foo
, then its size and signedness is implementation defined. It will be based on some existing integer type (that can store all the enum values), but which type is actually used can differ between implementations (and also between different enum
types).
来源:https://stackoverflow.com/questions/53681947/can-an-enum-hold-unsigned-integers-greater-than-int-max