【问题标题】:gcc suppress warning "too small to hold all values of"gcc 抑制警告“太小而无法容纳所有值”
【发布时间】:2016-06-30 12:37:09
【问题描述】:

我需要使用范围枚举,以便我可以将它们作为特定类型传递给我们的序列化程序。我已经为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++) 标志来禁用特定警告。有没有我可以在命令行上传递的?理想情况下,如果可能,我会使用警告编译指示在本地禁用它。

此时更改代码结构的余地很小,但我们确实可以使用删除这些虚假警告。

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

【问题讨论】:

  • 如果 Enum1 包含大于 3 的值,那么它将不适合 2 位
  • 你能说明Enum1Enum2的定义吗?
  • @nikniknik2016:没有
  • @jsren 然后创建一个人工minimal reproducible example 复制相同的问题,然后发布。对于我们看不到的代码,我们无能为力。
  • 虽然我不知道它的状态,但有这个gcc bug report

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


【解决方案1】:

问题是作用域枚举总是有一个完整的基础类型。默认为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 没有警告它。

【讨论】:

  • 干杯。我认为这是一个有用的警告。如果有更好的描述。而且真的只是第一次。我的主要问题是它对于每个字段和每个编译单元都会发生多次。尽管只使用了一次 g++ 调用。就此向开发者提出建议的最佳方式是什么?
【解决方案2】:

我记得,具有声明的基础类型的枚举可以保存该类型的任何值,而不管定义了哪些枚举常量。既然你可以说

val= enum2{148}

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

【讨论】:

  • 问题中的枚举没有声明的基础类型。但实际上规则是,如果存在固定基础类型,则基础类型的任何值都是有效的枚举值。并且作用域枚举(即enum class)总是有一个固定的底层类型,如果没有另外指定,它是int
猜你喜欢
  • 2015-08-01
  • 2021-12-23
  • 2023-02-01
  • 2012-10-02
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多