can an enum hold unsigned integers greater than INT_MAX?
Asked Answered
S

1

3
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 ¿?

Scutcheon answered 8/12, 2018 at 11:11 Comment(3)
For 32-bit int then 0x8000u is not even close to the limit. Do you mean 0x80000000u?Vivacious
Would you mind quoting the supposedly ambiguous formulation?Colossians
Yes I meant that, thank you :)Scutcheon
M
4

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

Mounts answered 8/12, 2018 at 11:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.