关于联合中使用自动生成赋值运算符复制重叠对象的行为疑问与编译器实现差异
关于联合中使用自动生成赋值运算符复制重叠对象的行为疑问与编译器实现差异
我遇到了一个关于C++联合(union)赋值的问题,具体场景如下:
在下面的程序里,union U的活跃成员是A类型的a,我们尝试用自动生成的operator=把它复制到同为联合成员的B类型对象b里,而B本身继承了A作为子对象:
#include <iostream> struct A { char c[7]; }; struct X { char x; }; struct B : X, A { using A::operator=; }; int main() { union U { A a{ 0, 1, 2, 3, 4, 5, 6 }; B b; } u; //#1 u.b = u.a; //#2 //u.b = A( u.a ); for ( int i = 0; i < 7; ++i ) std::cout << (int)u.b.c[i]; }
我本来期望程序输出0123456,但关闭优化后不同编译器给出了不一样的结果:
- MSVC:
0000000 - Clang:
0123355 - GCC 和 EDG:
0122356
问题1:是不是因为在复制过程中同时访问了联合的活跃和非活跃成员,导致程序出现未定义行为?
如果把u.b = u.a;改成先创建临时副本,用u.b = A( u.a );来赋值,那么MSVC和Clang的输出就符合预期的0123456了,但GCC和EDG还是输出0122356。
问题2:修改后的程序是良构的吗?那GCC和EDG的异常结果是不是属于实现bug?
备注:内容来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

