Description
Points:
- Each enumerator constant of the same enumeration may have different types during the definition of the enumeration until it is completed.
- The allowed type of an enumerator constant without a
=
definition is limited:
During the processing of each enumeration constant in the enumerator list, the type of the enumera-
tion constant shall be
...
— the type of the value from the previous enumeration constant with one added to it. If such
an integer constant expression would overflow or wraparound the value of the previous
enumeration constant from the addition of one, the type takes on either:
— a suitably sized signed integer type, excluding the bit-precise signed integer types, capable
of representing the value of the previous enumeration constant plus one; or,
— a suitably sized unsigned integer type, excluding the bit-precise unsigned integer types,
capable of representing the value of the previous enumeration constant plus one.
A signed integer type is chosen if the previous enumeration constant being added is of signed
integer type. An unsigned integer type is chosen if the previous enumeration constant is of
unsigned integer type. If there is no suitably sized integer type described previously which
can represent the new value, then the enumeration has no type which can represent all its
values.151)
— §6.7.2.2¶11, ISO/IEC 9899:2023 (E) working draft — April 1, 2023
enum E {
e0 = 0x7FFF, /* 'int' as always */
e1, /* 'unsigned int' in cc65, but 'long' according to C23 */
s0 = sizeof
6261
span> e0, /* s0 = 2 */
s1 = sizeof e1, /* cc65: s1 = 2 or C23: s1 = 4 */
e2 = 0x7FFFFFFF, /* 'long' */
//e3, /* 'unsigned long' in cc65, but constraint violation (!) without 'long long' according to C23 */
}; /* Now the enumerators shall have the same enumeration member type eg. 'long',
which is compatible with the underlying type of the enumeration */
_Static_assert(s0 == sizeof e0); /* cc65: OK; C23: fail? */
_Static_assert(s1 == sizeof e1); /* cc65: OK; C23: OK? */
_Static_assert(sizeof e2 == sizeof (enum E)); /* cc65 & C23: OK */
Should the current behavior of cc65 be "fixed" or kept as-is?
BTW, this shows how annoying the "good old enumerations" are, even with (or thanks to) compiler extensions. Any interests in enumerations with fixed underlying types from C23?