与const和nonconst成员的联合?

Joh*_*itb 21 c++ const undefined-behavior unions

这似乎是未定义的行为

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

A a = { 0 };
a.y = 1;
Run Code Online (Sandbox Code Playgroud)

规范说

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

但是没有编译器警告我,因为它很容易诊断错误.我是否误解了措辞?

Ton*_*nyK 7

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

在并集中,至多一个非静态数据成员可以在任何时间处于活动状态,也就是说,任何时候最多一个非静态数据成员的值都可以存储在并集中.

所以你的陈述

a.y = 1;
Run Code Online (Sandbox Code Playgroud)

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

cout << a.x << endl ; // Undefined!
Run Code Online (Sandbox Code Playgroud)

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

  • @Johannes:那很残酷.所以`struct Foo {const int a; }; char x [sizeof(Foo)]; Foo*p = new(x)Foo(); P->〜富(); x [0] = 0;`是未定义的行为?`x [0]`在生命周期结束之前位于const对象的位置.或者即使`x [0] = 0;`不"创建一个对象",重复`new(x)Foo();`肯定会. (2认同)

Ebo*_*ike 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
Run Code Online (Sandbox Code Playgroud)

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

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

  • Visual C++ 2010 给出相同的警告(使用“/W4”)。该警告 (C4610) 很有趣,因为它是错误的:“A”确实可以实例化,如“A x = { 0 };”(Visual C++ 2010 确实接受)所示。 (3认同)