什么时候初始化器暂时销毁?

Joh*_*itb 17 c++ initialization language-lawyer temporary-objects order-of-execution

在回答了一些问题之后,我今天构建了这个实验

struct A { 
  bool &b; 
  A(bool &b):b(b) { } 
  ~A() { std::cout << b; }  
  bool yield() { return true; } 
}; 

bool b = A(b).yield();

int main() { }
Run Code Online (Sandbox Code Playgroud)

bfalsetrue通过动态初始化将其设置为有值之前(由初始化为零).如果临时在b完成初始化之前被销毁,我们将打印false,否则true.

该规范说明临时在完整表达结束时被销毁.这似乎没有与初始化一起订购b.所以我想知道

  • 规范是否允许实现同时打印falsetrue不同的运行?

false用于上述的Clang打印,而GCC打印true.这让我很困惑.我是否错过了定义订单的规范文本?

Jer*_*fin 8

我认为允许打印出真实或错误,或者出于某些无关的原因,一无所获.

真正的或错误的部分是(正如你所说的),临时A对象的破坏不是关于动态初始化的有序b.

没有任何可能性是因为初始化b没有按照创建/初始化的顺序排序std::cout; 当你试图销毁临时文件时,cout可能尚未创建/初始化,因此尝试打印某些东西可能根本不起作用.[编辑:这是特定于C++ 98/03,并不适用于C++ 11.]

编辑:这是我至少看到序列的方式:

在此输入图像描述

编辑2:在重读§12.2/ 4(再次)后,我再次更改了图表.§12.2/ 4说:

有两种情况,临时表在与完整表达结束时不同的点被销毁.第一个上下文是表达式作为定义对象的声明符的初始值设定项.在该上下文中,保存表达式结果的临时值将持续存在,直到对象的初始化完成.该对象从临时副本初始化; 在此复制过程中,实现可以多次调用复制构造函数; 复制后,初始化完成之前或之后,临时都会被销毁.

我相信这个表达式是定义对象的声明true符的初始化器,因此需要从表达式的值的副本(在本例中)初始化对象,而不是直接从返回值初始化.在这种情况下true,这可能是一个没有区别的区别,但我认为该图表在技术上更加准确,因为它现在正是如此.

这也使得相当清楚(我认为)暂时保存true没有必须在充分表达年底被破坏,所以我重新绘制的图表,以反映这一点.

这部分在C++ 0x/C++ 11中消失了,所以我重新绘制了图表(再次)以显示两者之间的差异(以及这篇文章在C++ 11中的简单程度) .

  • @litb:如果`bool b = true; b = false;`是UB,然后我认为这是标准中的严重缺陷. (2认同)