【发布时间】:2014-03-24 10:13:10
【问题描述】:
警告:
src/BoardRep.h:49:12: warning: ‘BoardRep::BoardRep::Row::<anonymous struct>::a’
is too small to hold all values of ‘enum class BoardRep::Piece’
[enabled by default]
Piece a:2;
^
枚举:
enum class Piece: unsigned char {
EMPTY,
WHITE,
BLACK
};
用途:
union Row {
struct {
Piece a:2;
Piece b:2;
Piece c:2;
Piece d:2;
Piece e:2;
Piece f:2;
Piece g:2;
Piece h:2;
};
unsigned short raw;
};
对于enum,我同意GCC,它可能必须截断,但这是因为enums 并没有真正与整数和预处理器定义分开。然而enum class 更强大。如果它不足以假设所有Piece 值作为整数将介于 0 和 2 之间(含),则警告是有意义的。否则 GCC 是不必要的挑剔,可能值得邮寄名单说“看,这是一个愚蠢的警告”
以防有人看不到重点
您可以在 2 位数据中存储 4 个不同的值,我只需要 3 个不同的值,因此任何长度为 4 或更少的枚举都应该很好地适合给定的 2 位(并且我的枚举确实“导出”(更好的术语? ) 来自无符号类型)。如果我有 5 个或更多 THEN,我会收到警告。
【问题讨论】:
-
为什么首先使用枚举作为位字段的基础类型?
-
@KerrekSB 如果我不这样做,我必须定义一个允许
unsigned short由Piece分配的运算符。我在这里是说这个结构的前 2 位应命名为a并且在我处理它时应为Piece类型。 -
我和 Alec 的动机相同:我想使用整数的类型化切片(为了清晰和重载)。所有位域都存储可能值的子集(除非声明与类型一样宽);主观上,我不想要警告,因为这是“我的编程风格中的一个理性习语”(我正在从 clang++/MacOS 移植到 gcc/Linux),除非它不符合我声明的所有值(这是关于我实际想要存储在位域中的内容的提示!)。如果有人知道 gcc 命令行选项会专门关闭此警告,请分享。
-
@DanielMGessel 请查看高度评价的“答案”