这看起来与POD structs containing constant member类似,但有些相反 .
#include <iostream>
struct A
{
int a;
};
union U
{
volatile A a;
long b;
};
int main()
{
U u1;
U u2;
u1.a.a = 12;
u2 = u1;
std::cout << u2.a.a << std::endl;
return 0;
}
g 4.8.3编译此代码时没有错误并且运行正常:
$ g++ -std=c++03 a.cpp -o a_gcc
$ ./a_gcc
12
但是clang 3.5.1会产生错误(我手动包装了错误消息以防止代码框滚动):
$ clang++ -std=c++03 a.cpp -o a_clang
a.cpp:8:7: error: member function 'operator=' not viable: 'this'
argument has type 'volatile A', but function is not marked volatile
union U
^
a.cpp:3:8: note: 'operator=' declared here
struct A
^
a.cpp:20:5: note: implicit copy assignment operator for 'U' first
required here
u2 = u1;
^
1 error generated.
C 03是否允许程序复制 - 分配包含volatile结构的联合?我在C 03标准中找不到任何定义联合的默认复制构造函数的东西 .
我想知道哪个编译器是正确的,或者标准在那一点上是不清楚的 .
Edit: 我发现如果我使用复制构造而不是复制赋值,clang和g都会编译程序而不会出错 . 具体来说,如果我将 main
更改为:
int main()
{
U u1;
u1.a.a = 12;
U u2 = u1;
std::cout << u2.a.a << std::endl;
return 0;
}
..然后它会工作 . 我想知道为什么他们被clang对待他们 .
1 回答
在C 11中,可以删除union的复制构造函数 . 我们从[class.union]中的一个注释中看到了这一点,N4140中的§9.5:
在[class.copy],§12.8/ 25中,我们看到
union
有一个非平凡的复制构造函数:但是[class.copy]中的那个特定行只添加了Is a volatile-qualified type really a POD?的结果 . 在此之前,这样的类仍然被认为具有一个简单的复制构造函数 .
所以我的理解是,在C 03中,没有迹象表明联盟的复制构造函数应该被删除,而在C 11中,有一些迹象表明这一点,但它是非规范性的 .