gcc suppress warning "too small to hold all values of"

Viewed 3831

I need to use scoped enums so that I can pass them as specific types to our serialiser. I have given explicit integer values for the enum members of Enum1.

I have put two scoped enums matching the description above into a bitfield thus

enum class Enum1 {
    value1 = 0x0,
    value2 = 0x1,
    value3 = 0x2
};
enum class Enum2 {
    value1 = 0x0,
    value2,
    value3,
 // ...
    value14
};

struct Example {
    Enum1 value1 : 2;
    Enum2 value2 : 6;
}

Now wherever I use the Example type, I get the warning "'Example::value1' is too small to hold all values of 'Enum1'", and similarly for Enum2. Note that this is not the case for the values we have defined and we are not concerned at all with values outside of these.

This is quite a serious distraction in our build process - the project is large and complex and we don't want to have to scan through many of these warnings (and there are many).

I had a look for a GCC (G++) flag to disable the specific warning. Is there one that I can pass on the command line? Ideally, I would use the warning pragma to disable it locally, if possible.

There is little scope for changing the code structure at this point, but we could really use these spurious warnings removed.

Edit: Added scoped enums with identifiers changed.

4 Answers

As I recall, an enum with a declared underlying type can hold any value of that type, regardless of what enumeration constants are defined. Since you can say

val= enum2{148}

and expect it to work properly, the warning seems correct for that case. You are not declaring a base type, and historically this means that the enum is only guaranteed to be big enough to hold the range of values given by the lowest through highest enumeration constant. So I would expect no warning here. Maybe the new enum class also expects a full range even though the underlying type was automatically determined (or the compiler thinks it does)? You might try using a pure old-syntax enum and see if that works any differently.

Emitting this warning is a bug, because all declared enumerator (values) in fact can be held by the bitfield fields.

Like with traditional enums, a variable of scoped enum type still can hold any value of its underlying type, even ones that don't correspond to a declared enumerator.

However, warning about this like this

warning: 'some bitfield field' is too small to hold all values of 'enum class FOO'

is quite pointless because assigning a too large value as in

Example x;
x.value1 = Enum1(8);

already generates a -Woverflow warning.


Consequently, GCC fixed this warning in version 9.3.

FWIW, Clang never warned about.


IOW, to suppress this warning in GCC you have to upgrade to GCC version 9.3 or later.

For other people like me who end up here from search:

This problem only applies to C++11 scoped enums. If you need bitfield enums, old style enums without explicit storage size work fine:

enum Enum1 {
    Enum1_value1 = 0x0,
    Enum1_value2 = 0x1,
    Enum1_value3 = 0x2
};
enum Enum2 {
    Enum2_value1 = 0x0,
    Enum2_value2,
    Enum2_value3,
 // ...
    Enum2_value14
};

struct Example {
    Enum1 value1 : 2;
    Enum2 value2 : 6;
}
Related