c++ - 初始化器究竟是什么时候被临时销毁的?

标签 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() { }

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

规范说临时在完整表达式结束时被销毁。这似乎与 b 的初始化无关。所以我想知道

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

Clang 为上述打印 false,而 GCC 打印 true。这让我很困惑。我错过了一些定义订单的规范文本吗?

最佳答案

我认为它可以打印出真假,或者出于某种不相关的原因,什么都没有。

真假部分是(正如您所说),临时 A 对象的销毁相对于 b 的动态初始化没有顺序.

没有任何可能是因为 b 的初始化相对于 std::cout 的创建/初始化没有顺序;当您尝试销毁临时文件时,cout 可能尚未创建/初始化,因此尝试打印某些内容可能根本不起作用。 [编辑:这是 C++98/03 特有的,不适用于 C++11。]

编辑:至少我是这样看待序列的:

enter image description here

Edit2:在重读 §12.2/4(再次)之后,我再次更改了图表。 §12.2/4 说:

There are two contexts in which temporaries are destroyed at a different point than the end of the full expression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete. The object is initialized from a copy of the temporary; during this copying, an implementation can call the copy constructor many times; the temporary is destroyed after it has been copied, before or when the initialization completes.

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

这也很清楚(我认为)临时持有 true 确实 not 必须在完整表达式的末尾被销毁,所以我重新- 绘制图表以反射(reflect)这一点。

这部分在 C++0x/C++11 中消失了,所以我重新绘制了图表(再次)以显示两者之间的区别(以及这部分在 C+ 中变得多么简单+11)。

关于c++ - 初始化器究竟是什么时候被临时销毁的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5760866/

相关文章:

c++ - 从 char* 获取 istream

arrays - 你如何在 matlab 中初始化一个包含 90 个 '0' 的数组?

c++ - 如果括号里是case,需要换行吗?

c++ - Boost rng vs OpenCV rng vs c++11 std::random?

c++ - Boost几何点初始化

objective-c - 在 Objective-C 中调用指定的初始化器之后如何执行额外的初始化? ( self =[ self ...)

c - 严格的别名规则背后的基本原理是什么?

c++ - 从未使用过的无效默认成员初始值设定项

java - Eclipse 或 Javac 错误; lambda 类型推断

android - 使用 ./configure 为 Android 生成 config.h 时使用什么主机和目标?