如果我编写以下代码,该代码在 Code::Blocks GCC 上编译:
struct ByteSize
{
unsigned char Test:64;
};
ByteSize 结构的大小为 8。这是有道理的。但是当我访问 ByteSize 的测试时,它是否仍被视为无符号字符或其他变量?这很危险吗?我真的应该这样做吗?编译器会将 8 字节变量转换为单字节字符吗?
如果我编写以下代码,该代码在 Code::Blocks GCC 上编译:
struct ByteSize
{
unsigned char Test:64;
};
ByteSize 结构的大小为 8。这是有道理的。但是当我访问 ByteSize 的测试时,它是否仍被视为无符号字符或其他变量?这很危险吗?我真的应该这样做吗?编译器会将 8 字节变量转换为单字节字符吗?
浏览标准,我在 §9.6 中发现:
常量表达式可能大于位字段类型的对象表示(3.9)中的位数;在这种情况下,额外的位被用作填充位并且不参与位域的值表示(3.9)。
Test
是一个位域,它不是无符号字符或其他类型。这是危险的,因为它假定 unsigned char 可以容纳 64 位或更多位。你不应该真的这样做。我没有记住所有的转换规则,但是编译器不应该将 8 字节的非字符转换为字符,除非你明确告诉它(例如使用强制转换)。
...
你在找uint64_t
吗?
Clang 发出警告:
warning: size of bit-field 'Test' (64 bits) exceeds the size of its type;
value will be truncated to 8 bits
此外,如果尝试将大于 255 的值存储到其中,则会发出警告:
warning: implicit conversion from 'int' to 'unsigned char' changes
value from 256 to 0
然后,尝试从中读取会产生 0。因此,即使sizeof(ByteSize) == 8
它看起来只是将其作为无符号字符访问,并且它不希望您实际上可以在成员中存储超过 1 个字节。
宣言
struct ByteSize
{
unsigned char Test:64;
}
是不正确的。位域应该只使用裸无符号类型。
struct ByteSize
{
unsigned Test:64;
}
该值是无符号的,因此不会混淆符号位。该字段被视为所选字段大小的无符号整数。