gcc抑制警告“太小而无法容纳所有值”

时间:2016-03-15 07:34:48

标签: c++ gcc enums bit-fields suppress-warnings

我需要使用作用域枚举,以便我可以将它们作为特定类型传递给我们的序列化程序。我为Enum1的枚举成员提供了显式整数值。

我已将两个与上述描述相匹配的范围内的枚举放入一个位域

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;
}

现在无论我在哪里使用Example类型,我都会收到警告“'Example :: value1'太小而无法容纳'Enum1'的所有值”,对于Enum2也是如此。请注意,我们定义的值不是这种情况,我们并不关心所有的值超出这些值。

这在我们的构建过程中是一个非常严重的分心 - 项目庞大而复杂,我们不希望扫描其中的许多警告(并且有很多)。

我找了一个GCC(G ++)标志来禁用特定警告。有没有我可以通过命令行?理想情况下,如果可能的话,我会使用警告编译指示在本地禁用它。

此时几乎没有更改代码结构的余地,但我们确实可以删除这些虚假警告。

编辑:添加了标识符已更改的范围化枚举。

2 个答案:

答案 0 :(得分:12)

问题是作用域枚举始终具有整体底层类型。默认情况下,它是int,但您可以将其更改为任何其他整数类型,例如unsigned char

不幸的是,您无法将基础类型更改为位字段,因为它们不是真正的C ++类型。

您可以尝试禁用警告,但快速浏览G ++代码会显示这些行(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);

此处的关键是拨打warning_at(...)而不是warning(OPT_to_disable_the_warning, ...)。所以目前没有选项可以禁用它。除了自己重新编译编译器!

值得注意的是CLang ++ - 3.7.1没有警告它。

答案 1 :(得分:2)

我记得,无论定义了什么枚举常量,具有声明的基础类型的枚举都可以保存该类型的任何值。既然你可以说

val= enum2{148}

并期望它正常工作,这种情况的警告似乎是正确的。你并没有声明一个基类型,而且从历史上看,这意味着枚举只能保证足够大,以保持最低到最高枚举常数给出的值范围。所以我希望这里没有任何警告。也许新的enum class也期望一个完整的范围,即使底层类型是自动确定的(或者编译器认为它确实如此)?您可以尝试使用纯旧的语法枚举,看看它是否有所不同。