未指定的隐式对象创建

wal*_*nut 11 c++ language-lawyer c++20

由于P0593 为低级对象操作隐式创建对象已被接受,因此现在可以在 C++20 中隐式创建对象。

具体而言,提案中引入的措辞允许某些操作(例如std::malloc)自动创建和启动某些类型的对象的生命周期,即所谓的隐式生命周期类型如果此类对象的引入会导致具有其他未定义行为的程序具​​有定义的行为。见[intro.object]/10

该草案现在进一步指出,如果可以隐式创建多个此类对象集以提供程序定义的行为,则未指定创建这些对象中的哪一个。(相关句子似乎没有出现在我可以访问的最后一个提案修订版中,R5,但在提交草案中。)

实际上是否有一个程序可以观察到这种隐式创建的对象集的选择?换句话说,是否有一个程序通过这个新规则定义了但未指定的行为,以便可以从输出推断出哪些类型的隐式对象(从多个可能的对象中)被创建?

还是这句话只是为了澄清抽象机器上的程序执行(没有可观察到的影响)?

Bar*_*rry 9

我们以标准中的例子为例,稍微改动一下:

#include <cstdlib>
struct X { int a, b; };
X *make_x() {
  // The call to std::malloc implicitly creates an object of type X
  // and its subobjects a and b, and returns a pointer to that X object
  // (or an object that is pointer-interconvertible ([basic.compound]) with it),
  // in order to give the subsequent class member access operations
  // defined behavior.
  X *p = (X*)std::malloc(sizeof(struct X) * 2); // me: added the *2
  p->a = 1;
  p->b = 2;
  return p;
}
Run Code Online (Sandbox Code Playgroud)

以前,只有一组可以在该存储中隐式创建的有效对象 - 它必须恰好是一个X。但是现在,我们有两个Xs 的存储空间,但只写入其中一个,并且该程序中的任何内容都不会触及其余字节。因此,可以隐式创建许多不同的对象集 - 可能是两个X,可能是一个X和两个int,可能是一个X和八个char,......

创建哪个集合是不可观察的,因为如果有任何实际观察,那会将可能性减少到只有那些有效的集合。如果我们做了类似p[1]->a = 3的事情,那么可能性的世界就会坍缩成只有两个Xs 的那个。

换句话说,只有当程序中没有足够的观察来区分它们的有效性时,多组隐式创建的对象才有可能。如果有办法区分,那么根据定义,它们不会都是有效的。

  • 即使在最初的示例中,也可以创建一个数组对象以及一个“X”对象。 (2认同)