2

如果我编写以下代码,该代码在 Code::Blocks GCC 上编译:

struct ByteSize
{
   unsigned char Test:64;
};

ByteSize 结构的大小为 8。这是有道理的。但是当我访问 ByteSize 的测试时,它是否仍被视为无符号字符或其他变量?这很危险吗?我真的应该这样做吗?编译器会将 8 字节变量转换为单字节字符吗?

4

3 回答 3

1

浏览标准,我在 §9.6 中发现:

常量表达式可能大于位字段类型的对象表示(3.9)中的位数;在这种情况下,额外的位被用作填充位并且不参与位域的值表示(3.9)。

Test是一个位域,它不是无符号字符或其他类型。这是危险的,因为它假定 unsigned char 可以容纳 64 位或更多位。你不应该真的这样做。我没有记住所有的转换规则,但是编译器不应该将 8 字节的非字符转换为字符,除非你明确告诉它(例如使用强制转换)。

...

你在找uint64_t吗?

于 2012-10-29T03:45:44.033 回答
1

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 个字节。

于 2012-10-29T01:17:57.617 回答
1

宣言

struct ByteSize
{
   unsigned char Test:64;
}

是不正确的。位域应该只使用裸无符号类型。

struct ByteSize
{
   unsigned Test:64;
}

该值是无符号的,因此不会混淆符号位。该字段被视为所选字段大小的无符号整数。

于 2012-10-29T04:14:32.303 回答