通过其成员的地址激活嵌套联盟是否合法?

She*_*evy 7 c++ c++11

以下代码是否合法(在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 []变量成员的块,并且允许这将使我当前在复制构造函数中的尝试变得更清晰.

将其分解为两个子问题:

  1. 是否boolptr通过访问barptr合法成员进行分配b.b是不活跃的?
  2. 是否有就地构建boolptr激活b.bb.b.b

可以参考该标准.

Cas*_*sey 2

与关于联合和类型双关的许多问题一样,不清楚您的程序是否已定义行为,尽管我强烈希望它在任何理智的实现中都能按预期运行。我可以肯定地说,这个程序

#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)