hachyderm.io is one of the many independent Mastodon servers you can use to participate in the fediverse.
Hachyderm is a safe space, LGBTQIA+ and BLM, primarily comprised of tech industry professionals world wide. Note that many non-user account types have restrictions - please see our About page.

Administered by:

Server stats:

9.2K
active users

Quiz: how did i dream up that C++ compilers optimized switches on enums as GCC and Clang do not in the link gcc.godbolt.org/z/4sz3xGxh5 ?

Maybe they don't in practice for C interoperability reasons, but i regret the time spent warning for “(more_enum)2” now.

Context: the sentence “Otherwise, the values of the enumeration are the values representable by a hypothetical integer type with minimal width M such that all enumerators can be represented” in eel.is/c++draft/enum#dcl.enum- applies here.

gcc.godbolt.orgCompiler Explorer - C++int x, y; enum more_enum { FA, TR} b; void f(void) { switch (b) { case TR: y++; break; case FA: x++; } }

A bit of a conclusion here to my request of yesterday…

So as Félix pointed out, I was looking for the optimization -fstrict-enums, which Clang and GCC kindly do not enable even at -O3.

This means that if you have legacy code that doesn't respect the rule that enums to which the sentence “Otherwise, the values of the enumeration are the values representable by a hypothetical integer type” applies only contain representable integers, you are still safe unless you go out of your way to activate this optimization by name.

And if you want to activate this optimization to get its benefits elsewhere, and need to fix one particular enum, it's also very simple, see the version in hashtag ifdef COMPILER_PROOF in:
gcc.godbolt.org/z/W4xqfazba

gcc.godbolt.orgCompiler Explorer - C++int x, y; #ifdef COMPILER_PROOF enum more_enum : unsigned { FA, TR} b; #else enum more_enum { FA, TR} b; #endif void f(void) { switch (b) { case TR: y++; break; case FA: x++; } }

Unusually for this account, the original post was a C++ example. The C standard doesn't have a nasty notion of “hypothetical integer type” just wide enough to contain the members of each particular enum. Instead, the compiler chooses a reasonable compatible integer type (GCC would choose “unsigned” on its own on the original example (barring the use of the ABI-breaking -fshort-enums option)).

And C23 adds support for the C++ syntax “enum bool_enum : unsigned { FA, TR } b;” to force the compatible type of an enum.

gcc.godbolt.org/z/q3dTKzcK9

gcc.godbolt.orgCompiler Explorer - C (x86-64 gcc (trunk))enum bool_enum1 { FA1, TR1 } b1; enum bool_enum2 : unsigned { FA2, TR2 } b2;
pinskia

@void_friend "barring the use of the ABI-breaking -fshort-enums option" Except some targets' ABI requires that (e.g arm eabi; at least for aarch64 abi arm decided not to do that by default).