can an enum hold unsigned integers greater than INT_MAX?

▼魔方 西西 提交于 2020-07-09 09:48:11

问题


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

  1. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!