以下代码是否合法(在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;
}
Run Code Online (Sandbox Code Playgroud)
这个例子很愚蠢,但是我正在使用一个可变参数variant实现,它使用嵌套联合而不是char []变量成员的块,并且允许这将使我当前在复制构造函数中的尝试变得更清晰.
将其分解为两个子问题:
boolptr通过访问barptr合法成员进行分配b.b是不活跃的?boolptr激活b.b和b.b.b?可以参考该标准.
与关于联合和类型双关的许多问题一样,不清楚您的程序是否已定义行为,尽管我强烈希望它在任何理智的实现中都能按预期运行。我可以肯定地说,这个程序:
#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;
}
Run Code Online (Sandbox Code Playgroud)
符合标准,具有您想要的效果,并且在现代编译器中编译为与原始程序完全相同的程序集。原来的:
foo():
movl $1, %eax
ret
Run Code Online (Sandbox Code Playgroud)
保证合规:
foo():
movl $1, %eax
ret
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |