这是否会遇到有关对象生命周期的未定义行为?

时间:2011-04-20 15:55:54

标签: c++ undefined-behavior

#include "stdio.h"

class C {
 public:
  ~C() { printf("~C\n"); }
};

int I(const C& c) { printf("I\n"); return 0; }
void V(int i) { printf("V\n"); }

int main() {
  V(I(C()));
  return 0;
}

看到输出:

I
V
~C

我的期望:

I
~C
V

4 个答案:

答案 0 :(得分:4)

V(I(C()));

C()会创建一个暂时的,直到完整表达式完成,完整表达式的完成为;(即分号)。这就是为什么你看到我认为输出定义明确的原因。

标准中的第12.2 / 3节,

  

[...]作为评估的最后一步,临时对象被销毁   完整表达(1.9)(词法上)包含创建它们的点。即使该评估以抛出异常结束,也是如此。

要强调的是,在此示例中,临时的生命周期与函数I()引用 const引用参数无关。即使I()的签名是:

int I(C c); //instead of : int I(const C & c);

暂时会持续到完整表达式完成后,您会看到完全相同的输出。

请参阅:http://www.ideone.com/RYWhy

答案 1 :(得分:3)

在完全评估完整表达式之前,对V的调用返回。当V返回时,它会打印出它的东西(在从V返回之前有一个序列点)。

只有在评估完整的完整表达式后才会销毁临时C()

答案 2 :(得分:1)

为什么呢?临时生活直到完整表达结束。

答案 3 :(得分:1)

您所看到的行为是标准规定的行为:临时行为在创建它们的完整表达式结束时被销毁。

历史上看到了另一种行为(并且在某些编译器中仍然可用):块结束时的破坏。在你的情况下,它不会产生任何影响,因为它会进一步推迟破坏。