cppreference † 声明:
Objects with trivial default constructors can be created by using
reinterpret_cast
on any suitably aligned storage, e.g. on memory allocated withstd::malloc
.
这意味着以下是定义良好的代码:
struct X { int x; };
alignas(X) char buffer[sizeof(X)]; // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)
以下三个问题:
- 这句话对吗?
- 如果是,
X
的生命周期从什么时候开始?如果在(B)
行,是 Actor 本身被认为是获取存储空间吗?如果在(A)
行,如果在(A)
和(B)
之间有一个分支会有条件地构造一个怎么办? X
或其他一些 pod,Y
? - 在这方面 C++11 和 C++1z 之间有什么变化吗?
†请注意,这是一个旧链接。针对这个问题改变了措辞。现在是这样的:
Unlike in C, however, objects with trivial default constructors cannot be created by simply reinterpreting suitably aligned storage, such as memory allocated with
std::malloc
: placement-new is required to formally introduce a new object and avoid potential undefined behavior.
最佳答案
没有 X
对象,无论是活的还是其他的,所以假装有一个会导致未定义的行为。
[intro.object]/1在创建对象时详细说明:
An object is created by a definition ([basic.def]), by a new-expression ([expr.new]), when implicitly changing the active member of a union ([class.union]), or when a temporary object is created ([conv.rval], [class.temporary]).
通过P0137R1 ,本段是“对象”一词的定义。
有 X
对象的定义吗?没有。有 new-expression 吗?没有。有 union 吗?否。您的代码中是否存在创建临时 X
对象的语言结构?没有。
无论 [basic.life] 对具有空初始化的对象的生命周期说什么都是无关紧要的。为此,您必须首先拥有一个对象。你没有。
C++11 有大致相同的段落,但不使用它作为“对象”的定义。尽管如此,解释是一样的。另一种解释——一旦获得合适的存储就将 [basic.life] 视为创建对象——意味着您正在创建薛定谔的对象*,这与 N3337 [intro.object]/6 相矛盾。 :
Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses.
* 对于类型 T
具有正确对齐和大小的存储,根据定义,对于 所有其他类型 的大小和对齐要求等于或小于 T
的要求。因此,该解释意味着获得存储同时在所述存储中创建具有不同类型的无限对象集,所有对象都具有相同的地址。
关于c++ - reinterpret_cast 创建一个简单的默认构造对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40873520/