【发布时间】:2017-04-13 21:36:00
【问题描述】:
cppreference† 声明:
可以通过在任何适当对齐的存储上使用
reinterpret_cast创建具有琐碎默认构造函数的对象,例如在使用std::malloc分配的内存上。
这意味着以下是定义良好的代码:
struct X { int x; };
alignas(X) char buffer[sizeof(X)]; // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)
以下三个问题:
- 该引用正确吗?
- 如果是,
X的生命周期从什么时候开始?如果在线(B),是演员本身被认为是获取存储空间吗?如果在线(A),如果(A)和(B)之间有一个分支会有条件地构造一个X或其他一些pod,Y? - 在这方面,C++11 和 C++1z 之间有什么变化吗?
†请注意,这是一个旧链接。针对这个问题改变了措辞。现在是这样的:
然而,与 C 不同的是,不能通过简单地重新解释适当对齐的存储来创建具有微不足道的默认构造函数的对象,例如使用
std::malloc分配的内存:placement-new 需要正式引入新对象并避免潜在的未定义行为。
【问题讨论】:
-
我实际上试图弄清楚这些对象的生命周期何时开始的问题。我无法在标准中找到明确的答案,而且我相信,在这方面它是模糊的。至于第一个问题,我怀疑引用是否正确,因为需要注意一个别名规则。
-
@SergeyA 只要缓冲区是字符缓冲区,严格的别名就不是问题。
-
不,我以为我们已经多次讨论过这个问题了? [intro.object]/1 详尽列举了哪些语言结构可以创建对象。
-
@RichardHodges,不。
char*可以别名 anything,但 anything 不能别名char* -
@RichardHodges 实际上你可以使用(递归)联合,如果你想要
constexpr,必须使用一个。
标签: c++ c++11 language-lawyer c++17