以下代码是否合法(在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;
}
这个例子很愚蠢,但是我正在使用一个变量variant
实现,它使用嵌套联合而不是char []
块作为变体成员,并允许这将使我当前的尝试复制构造函数清理器。
将其细分为两个子问题:
boolptr
处于无效状态,访问barptr
成员是否合法,b.b
的分配是否仍然有效?boolptr
的就地构造是否会激活b.b
和b.b.b
?赞赏参考标准。
答案 0 :(得分:2)
正如有很多关于工会和打字的问题一样,我们还不清楚你的程序是否定义了行为,尽管我强烈期望它在任何理智的实现中表现得如预期。我可以用确信说的是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