Search code examples
c++gccenumsbit-fieldssuppress-warnings

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


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.


Solution

  • The problem is that an scoped enum always has an integral underlying type. By default, it is int but you can change it to any other integral type, such as unsigned char.

    Unfortunately you cannot change the underlying type to a bit-field, as they are not real C++ types.

    You could try disabling the warning, but a quick skim through the G++ code reveals these lines (gcc/cp/class.c:3468):

      else if (TREE_CODE (type) == ENUMERAL_TYPE
               && (0 > (compare_tree_int
                        (w, TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type))))))
        warning_at (DECL_SOURCE_LOCATION (field), 0,
                    "%qD is too small to hold all values of %q#T",
                    field, type);
    

    The key here is the call to warning_at(...) instead of warning(OPT_to_disable_the_warning, ...). So currently there is no option to disable it. Except recompiling the compiler yourself!

    For what it is worth CLang++-3.7.1 does not warn about it.