如何避免在 const 自动对象过去占用的存储中创建任何对象?

cur*_*guy 1 c++ constants local-variables placement-new language-lawyer

C++(草案)标准包含我所说的“ROMability 条款”,即[basic.life]/10

在具有静态、线程或自动存储持续时间的 const 完整对象占用的存储中,或在此类 const 对象在其生命周期结束之前曾经占用的存储中创建新对象,将导致未定义的行为。

第一部分很好:“静态,线程”“存储持续时间”。允许重复使用这种存储是不合理的。

但是最后一部分呢:

自动存储持续时间占用,或在此类 const 对象在其生命周期结束之前曾经占用的存储空间内

这是否意味着用户需要避免在堆栈可能已使用的任何内存位置创建任何对象(用于存储自动对象)

这将阻止在自动对象的任何子对象上使用新放置,或使用执行此类操作的库工具。

这是零意义的,但在我看来,它确实是这里指定的内容。

Dan*_*our 8

用户需要避免在堆栈可能已使用的任何内存位置创建任何对象(以存储自动对象)

该标准不知道“堆栈”,也不关心——这是一个实现细节。

未明确声明为 static、thread_local 或 extern 的块范围变量具有自动存储持续时间。

这些实体的存储会一直持续到创建它们的块退出

来自[basic.stc.auto]

因此,即使两个实体最终 - 没有重叠存储 - 在“堆栈上”的相同地址,它们仍然没有相同的存储。

union Lazy {
  Thing thing;
};

// later in a function
{
  Thing const first = /* init */
}
{
  Lazy l;
  new (&l.thing) Thing();
}
Run Code Online (Sandbox Code Playgroud)

first并且l.thing可能会在同一个地址上......但是当l.thing创建时,存储first已经“消失”了。

“底线”:相同的地址并不意味着相同的存储。