gcc 抑制警告 "too small to hold all values of"
gcc suppress warning "too small to hold all values of"
我需要使用作用域枚举,以便我可以将它们作为特定类型传递给我们的序列化程序。我已经为 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++) 标志来禁用特定警告。我可以在命令行上传递一个吗?理想情况下,如果可能的话,我会使用警告编译指示在本地禁用它。
此时更改代码结构的余地很小,但我们确实可以使用这些删除的虚假警告。
编辑:添加了标识符已更改的作用域枚举。
问题是作用域枚举总是有一个完整的基础类型。默认情况下,它是 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 没有对此发出警告。
我记得,具有声明的基础类型的枚举可以包含该类型的任何值,而不管定义的枚举常量是什么。既然你可以说
val= enum2{148}
并希望它能正常工作,对于这种情况,警告似乎是正确的。您没有声明基本类型,从历史上看,这意味着枚举只能保证足够大以容纳由最低到最高枚举常量给出的值范围。所以我希望这里没有警告。也许新的 enum class
也需要一个完整的范围,即使底层类型是自动确定的(或者编译器认为它是)?您可以尝试使用纯旧语法枚举,看看它是否有任何不同。
对于像我这样通过搜索最终来到这里的其他人:
此问题仅适用于 C++11 作用域枚举。如果您需要位域枚举,没有明确存储大小的旧式枚举也可以正常工作:
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;
}
我需要使用作用域枚举,以便我可以将它们作为特定类型传递给我们的序列化程序。我已经为 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++) 标志来禁用特定警告。我可以在命令行上传递一个吗?理想情况下,如果可能的话,我会使用警告编译指示在本地禁用它。
此时更改代码结构的余地很小,但我们确实可以使用这些删除的虚假警告。
编辑:添加了标识符已更改的作用域枚举。
问题是作用域枚举总是有一个完整的基础类型。默认情况下,它是 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 没有对此发出警告。
我记得,具有声明的基础类型的枚举可以包含该类型的任何值,而不管定义的枚举常量是什么。既然你可以说
val= enum2{148}
并希望它能正常工作,对于这种情况,警告似乎是正确的。您没有声明基本类型,从历史上看,这意味着枚举只能保证足够大以容纳由最低到最高枚举常量给出的值范围。所以我希望这里没有警告。也许新的 enum class
也需要一个完整的范围,即使底层类型是自动确定的(或者编译器认为它是)?您可以尝试使用纯旧语法枚举,看看它是否有任何不同。
对于像我这样通过搜索最终来到这里的其他人:
此问题仅适用于 C++11 作用域枚举。如果您需要位域枚举,没有明确存储大小的旧式枚举也可以正常工作:
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;
}