与const和nonconst成员的联合?

时间:2011-04-13 17:55:38

标签: c++ const undefined-behavior unions

这似乎是未定义的行为

union A {
  int const x;
  float y;
};

A a = { 0 };
a.y = 1;

规范说

  

在存储位置创建一个具有静态,线程或自动存储持续时间的const对象占用的新对象,或者在这个const对象在其生命周期结束之前占用的存储位置导致未定义的行为。

但是没有编译器警告我,因为这是一个容易诊断的错误。我是否误解了措辞?

3 个答案:

答案 0 :(得分:7)

最新的C ++ 0x草案标准明确指出:

  

在联合中,最多只有一个非静态数据成员可以在任何时候处于活动状态   时间,即至多一个非静态数据成员的值即可   随时存放在工会中。

所以你的陈述

a.y = 1;

很好,因为它会将有效成员从x更改为y。如果您随后将a.x引用为右值,则行为将是未定义的:

cout << a.x << endl ; // Undefined!

您在此处引用的引用与此无关,因为您没有创建任何新对象。

答案 1 :(得分:1)

如果有任何安慰 - Microsoft Xbox 360编译器(基于Visual Studio的编译器)会出错。这很有趣,因为这通常是最宽松的。

error C2220: warning treated as error - no 'object' file generated
warning C4510: 'A' : default constructor could not be generated
    : see declaration of 'A'
warning C4610: union 'A' can never be instantiated - user defined constructor required

如果我把const拿走,这个错误就消失了。基于gcc的编译器不会抱怨。

编辑:Microsoft Visual C ++编译器具有相同的警告。

答案 2 :(得分:1)

拥有const的{​​{1}}成员并没有多大意义,我很惊讶标准允许它。可以进入union的所有限制的目的是达到一个点,其中按位赋值将是所有成员的有效赋值运算符,并且您不能使用按位赋值来分配给union。我的猜测是,这只是一个没有人曾经想过的情况(尽管它影响C和C ++,所以它已经存在了一段时间)。