On Fri, Jul 23, 2021 at 7:40 AM Petr Viktorin <encukou@gmail.com> wrote:
[snip]
>     On 21. 07. 21 14:18, Nick Coghlan wrote:
[snip]
>     Please don't put the enum in the stable ABI. If we would add another
>     value and then an older extension would receive it, we'd get undefined
>     behavior.
>
>

After researching a bit more, I see that casting unknown values to enum
is only undefined/unspecified behavior in C++. But we do support C++
extensions, and so I'll try to get enums out of the stable ABI.

(In both C & C++, the size of an `enum` is implementation-defined.
That's unlikely to be a problem in practice, but one more point against
enum.)

I can't speak much for C, but for C++ this is fine I think? enums have the same range of values as their "underlying type" (see e.g. [basic.fundamental] and [dcl.enum]). Aside from representation, [expr.static.cast] explicitly allows conversion when in-range: "the value is unchanged if the original value is within the range of the enumeration values". (Note if you click the link -- "fixed underlying type" refers to a form of enum which doesn't exist in C; the C-like enums are the ones without a fixed underlying type.)

And as Larry points out, you can force the range of values to be as large as you want by specifying a large enumerator.

However, the standard is not meant for reading by us mere mortals, so I usually use cppreference, which has this to say at https://en.cppreference.com/w/cpp/language/enum :

Values of integer, floating-point, and enumeration types can be converted by static_cast or explicit cast, to any enumeration type. If the underlying type is not fixed and the source value is out of range, [the result is unspecified (until C++17) | the behavior is undefined (since C++17)]. [...] Note that the value after such conversion may not necessarily equal any of the named enumerators defined for the enumeration.

-- Devin