获取存储空间是什么意思?

What does it mean to obtain storage?

[basic.indet] p1 说:

When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced.

为对象获取存储空间到底意味着什么?考虑这个代码片段:

int a = 0;
new (&a) int;

什么时候获取由new-expression 创建的int 对象的存储空间?是在定义创建的原始对象的存储时获取,还是在new-expression创建对象时获取?

(旁注:根据P0593 this new object will have an indeterminate value due to [basic.life] p4,然而,这并没有明确指定,除非在创建第二个对象时认为存储被获取)

编辑:这似乎是未答复的缺陷报告的主题 CWG 1997

存储最初是为自动对象分配d。 placement-new 然后 重新使用 动态对象的存储。

该标准似乎没有定义 "obtain" 这个词在分配和重用方面的含义。如果它被限制为与 "allocate" 相同,那么它将是一个多余的术语,因此假设它涵盖分配和重用是合理的。

根据这种解释,存储将在放置新表达式时获得。事实上,价值是不确定的。有一个保持值的技巧:

int a = 0;
int orig = a;
new (&a) int(orig);

一个体面的优化编译器可以看到副本是多余的。对于数组,同样可以用memcpy实现,只要长度不变,也可以优化掉。

实际上,it's quite simple。来自 [expr.new]/8:

A new-expression may obtain storage for the object by calling an allocation function

Placement-new 是一个分配函数。它可能只 return 与它被赋予的指针相同,但这个过程仍然被认为是 "obtaining storage for the object"。该存储是 &a 指向的存储。因此,它完全按预期工作。 a 当前正在使用的存储正在重新使用。因此当前的 a 结束了它的生命周期,而新的 int 在同一个存储中开始了它的生命周期。

"Obtain storage for an object" 并不意味着 "make storage appear that wasn't there before"。它的意思正是它所说的:为了将对象放在那里而获得一块存储空间。这不同于简单地获得一块存储空间。这块存储空间可能已经被其他对象使用是正交的。