Bit-packing enums vs. enum classes

433 views
Skip to first unread message

Daniel Hofmann

unread,
Feb 10, 2016, 7:06:53 PM2/10/16
to std-dis...@isocpp.org
Dear all,

suppose you have an enum, you can bit-pack its values like this

enum E { X, Y }; struct S { E e : 1; };

and the compiler will issue a diagnostic if there are too many values

enum E { X, Y, Z }; struct S { E e : 1; };

> 'S::e' is too small to hold all values of 'enum E'

The next logical step is to try the same with enum classes, to avoid the
implicit conversion to integral types

enum class E { X, Y }; struct S { E e : 1; };

which surprisingly to me already results in this diagnostic

> 'S::e' is too small to hold all values of 'enum class E'


From what I can see the size of the enum classes' underlying type has to
be used to make it work

enum class E : char { X, Y }; struct S { E e :
sizeof(underlying_type<E>::type) * CHAR_BIT; };

which defeats the purpose of bit-packing.


In short, what is the rationale for allowing bit-packing with enums but
not with enum classes?


Cheers,
Daniel

Richard Smith

unread,
Feb 10, 2016, 8:00:48 PM2/10/16
to std-dis...@isocpp.org
You have a faulty assumption. The above diagnostics are compiler
warnings, not mandated by the standard.

The reason the compiler is warning on the second case but not the
first is that, for an enumeration with no fixed underlying type, the
range of values of the enumeration is restricted based on the range of
values of the enumerators, whereas for an enumeration with a fixed
underlying type, the range of values of the enumeration is the range
of representable values of the underlying type.

In code:

enum E { X, Y }; struct S { E e : 1 };
E e = (E)2; // undefined behavior, 2 is not in the range of
representable values of type E
S s = {e};

enum class E { X, Y }; struct S { E e : 1 }; // compiler warning:
bit-field too small
E e = (E)2; // OK
S s = {e}; // oops

If this bothers you, maybe you could ask your compiler vendor to
suppress the warning in this case?

Jens Maurer

unread,
Feb 10, 2016, 8:02:08 PM2/10/16
to std-dis...@isocpp.org

Can you point to specific wording in the standard that makes one
case well-formed and the other one ill-formed?

All you do is quote compiler error messages, but your compiler
might actually have a bug.

Jens
Reply all
Reply to author
Forward
0 new messages