未指定的隐式对象创建


9

自从接受了P0593用于低级对象操作的对象隐式创建以来,现在可以在C ++ 20中隐式创建对象。

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

草案现在进一步指出,如果可以隐式创建多个这样的对象集以赋予程序定义的行为,则未指定创建这些对象集中的哪个。(有关的句子似乎没有出现在我可以访问的上一个提案修订版R5中,而是在提交草案中。)

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

还是这句话只是为了阐明程序在抽象机上的执行(没有明显的影响)?


2
(OT)如果隐式创建的对象是int,我们可以将其称为“隐式int”吗?
MM

似乎不清楚在malloc时是否必须知道未指定集合中元素的选择
MM

@MM我假设set的选择被认为是整个程序在执行流程之外执行的抽象选择,但是创建直接在相关操作(即std::malloc)上进行,否则定义会出现问题递归地取决于未来。
胡桃木

我对该主题提出了另一个问题,stackoverflow.com/ questions/ 60627249 。当然会想到更多的推论,但一次有一个问题..
MM

该提案声称不可能如此区分,这很重要,因为没有办法“正确地”做出选择,只有避免这种情况的优化才是(非常严格)有效的。
戴维斯鲱鱼

Answers:


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;
}

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

创建哪个集合是不可观察的,因为如果有任何实际的观察,那将把可能性减少到只有那些有效的集合。如果我们做类似的事情,p[1]->a = 3那么可能性的宇宙就会崩溃为只有2 X的可能性。

换句话说,只有当程序中没有足够的观察值来区分其隐含性时,才可能有多个隐式创建的对象集。如果有一种区分的方法,那么按照定义,它们将不是全部有效。


无论如何,这只是我的猜测。
巴里

因此,我认为,没有没有未定义行为的情况,根本就没有办法区分/观察不同隐式生命类型对象的存在与否。在那种情况下,在我看来,标准中“唯一性行为 ” 的唯一使用实际上并不能导致不同的可观察结果。
核桃木

1
或者,如果只访问是通过类型glvalues [简历] charunsigned charstd::byte?我猜,任何琐碎可复制类型的对象也可能在那里存在?
aschepler

2
即使在原始示例中,也可以与一个对象一起创建一个数组X对象。
TC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.