reinterpret_cast/static_cast和未定义的行为

man*_*lio 7 c++ variant static-cast reinterpret-cast c++11

在一个变体类中,我正在处理原始存储是一个char数组:

alignas(/* the strictest alignment of all types of the variant */)
char storage[/* ... */];
Run Code Online (Sandbox Code Playgroud)

赋值运算符类似于:

template<class X>
void operator=(const X &x)
{
  // ...code for clearing the storage and setting the tag for type X...

  new(storage) X(x);
}
Run Code Online (Sandbox Code Playgroud)

获取存储对象的代码是:

template<class X>
const X &get()
{
  // ...
  return *reinterpret_cast<X *>(storage);
  // ...
}
Run Code Online (Sandbox Code Playgroud)

它似乎工作,但它总是很好定义?我担心安全地解除引用指针(类型别名规则允许它吗?).

当前的实施和之间是否存在任何差异

 return *static_cast<const X *>(static_cast<const void *>(storage));
Run Code Online (Sandbox Code Playgroud)

相关问题/答案:

/sf/answers/512527081/(见James Kanze的评论).


编辑

第二个问题已经有了答案:C++我们什么时候应该优先使用两个链式的static_cast而不是reinterpret_cast

Ser*_*sta 4

由于storage正确对齐,我无法想象哪里会出现问题。关于指针转换的段落(*) 4.10说:\xe2\x80\x9c类型的纯右值指向cv T,\xe2\x80\x9d,其中T是对象类型,可以转换为\xe2\x80类型的纯右值\x9c 指向 cv void\xe2\x80\x9d 的指针。将指向对象类型的指针的非空指针值转换为 \xe2\x80\x9c 指针到 cv void\xe2\x80\x9d 的结果表示与原始指针值在内存中相同字节的地址

\n\n

关于第二个问题,第 5.2.10\non 段 reinterpres_cast对象指针可以显式转换为不同类型的对象指针。当对象指针类型的纯右值 v 转换为对象指针类型 \xe2\x80\x9cpointer to cv T\xe2\x80\x9d 时,结果是static_cast<cv T*>(static_cast<cv void*>(v))其中cv代表可选constvolatile

\n\n

所以这部分是按规格保证的。更多的是我们看到演员阵容void *应该指向内存的第一个字节,对于我对标准的理解,没有 UB ...只要编译器有相同的理解;-)

\n\n

(*) R\xc3\xa9f\xc3\xa9rence :当前 C++ 规范的草案

\n