我正在使用C ++中的一些联盟,我正在尝试确定以下情况的定义行为:
假设我的联盟定义如下:
union word_t {
struct fields_t {
unsigned int x : 8;
unsigned int y : 8;
unsigned int height : 8;
unsigned int width : 8;
} fields;
unsigned int word;
} word;
然后我尝试像这样分配给它:
word.fields.x = 300;
我在VS2005中对此进行了实验,它似乎掩盖了超出范围的位并存储了有效的位,而没有对其他联合字段产生任何不利影响。这就是我预期会如何处理,但我找不到任何备份文档。这是定义的行为,还是特定于实现?
答案 0 :(得分:1)
对于字段值溢出来说,影响相邻变量(无论是位字段,整数,等等)都是一个主要的编译器错误。
工会的相关性逃脱了我。
答案 1 :(得分:1)
它按预期工作。 'x'变量将具有'word'的最重要的8位,'width'将具有'word'的最低8位。改变x只会改变'word'的最重要的8位。以下具有相同的效果:
const uint16_t N = 5;
word.word = static_cast<uint32_t>(N)<<24 | (word & 0x00FFFFFF);
word.x = N;
这不是特定于实现的。
答案 2 :(得分:1)
行为定义明确。根据C ++标准 4.7 [conv.integral] ,对无符号整数类型的操作以模2^n
为模执行,其中n
是用于表示类型的位数;这也适用于位字段。因此,word.fields.x = 300;
相当于word.fields.x = 44;
,因为300 == 44 (modulo 256)
。