为联合中的位域分配无效值

时间:2013-11-07 20:27:03

标签: c++ visual-c++

我正在使用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中对此进行了实验,它似乎掩盖了超出范围的位并存储了有效的位,而没有对其他联合字段产生任何不利影响。这就是我预期会如何处理,但我找不到任何备份文档。这是定义的行为,还是特定于实现?

3 个答案:

答案 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)