以下代码是否合法(在c 11/14中)?
bool foo() { union bar { int i; bool b; }; union baz { char c; bar b; }; auto b = baz{'x'}; auto barptr = &b.b; auto boolptr = &barptr->b; new (boolptr) bool{true}; return b.b.b; }
这个例子很愚蠢,但我正在使用一个可变参数变体实现,它使用嵌套联合而不是变量成员的char []块,并且允许这将使我当前在复制构造函数中的尝试变得更清晰.
将其细分为两个子问题:
>即使b.b处于非活动状态,是否通过访问barptr legal的成员来分配boolptr?
> boolptr的就地构造是否会激活b.b和b.b.b?
将赞赏对该标准的参考.
解决方法
正如关于工会和类型惩罚的许多问题一样,目前还不清楚你的程序是否已经定义了行为,尽管我强烈期望它在任何理智的实现中都能按预期运行.我可以肯定地说,this program:
#include <memory> #include <new> template <typename T> inline void destruct(T& t) { t.~T(); } template <typename T,typename...Args> inline void construct(T& t,Args&&...args) { ::new((void*)std::addressof(t)) T(std::forward<Args>(args)...); } template <typename T> inline void default_construct(T& t) { ::new((void*)std::addressof(t)) T; } bool foo() { union bar { int i; bool b; }; union baz { char c; bar b; }; auto b = baz{'x'}; destruct(b.c); default_construct(b.b); construct(b.b.b,true); return b.b.b; }
符合标准,具有您想要的效果,compiles to exactly the same assembly as the original program in modern compilers.Original:
foo(): movl $1,%eax ret
foo(): movl $1,%eax ret