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

发布于 2024-11-02 16:17:10 字数 315 浏览 1 评论 0原文

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

Seen output:

I
V
~C

what I would have expected:

I
~C
V

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

稀香 2024-11-09 16:17:10
V(I(C()));

C() 创建一个临时变量,该临时变量持续直到完整表达式完成,并且完整表达式的完成是 ;< /code>(即分号)。这就是为什么你会看到我认为输出是明确定义的。

标准第 §12.2/3 节内容如下:

[...] 临时对象在评估的最后一步被销毁
完整表达式
(1.9)(在词法上)包含它们被创建的点。即使该评估最终引发异常也是如此。

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

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

临时值将持续到完整表达式完成,并且您将看到完全相同相同的输出。

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

V(I(C()));

C() creates a temporary which persists till the completion of the full expression, and the completion of the full expression is ; (i.e the semicolon). That is why you see that output which is in my opinion is well-defined.

Section §12.2/3 from the Standard reads,

[...] Temporary objects are destroyed as the last step in evaluating
the full-expression
(1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception.

Just to emphasize, in this example the lifetime of the temporary has nothing to do with the reference or const reference parameter of function I(). Even if the signature of I() is:

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

the temporary would persist till the completion of the full expression and you would see exactly the same output.

See this: http://www.ideone.com/RYWhy

时光匆匆的小流年 2024-11-09 16:17:10

V 的调用在完整表达式完全求值之前返回。当V返回时,它将打印其内容(从V返回之前有一个序列点)。

临时的 C() 仅在完整的完整表达式求值后才会被销毁。

The call to V returns before the full expression has been completely evaluated. And when V has returned, it will have printed its stuff (there is a sequence point before returning from V).

The temporary C() is only destroyed after the complete full expression has been evaluated.

诗酒趁年少 2024-11-09 16:17:10

为什么?临时的生命直到完整表达结束为止。

Why? The temporary lives till the end of the full expression.

浅浅 2024-11-09 16:17:10

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

历史上曾出现过另一种行为(并且在某些编译器中仍然可用):在块末尾进行销毁。就您而言,这不会产生任何影响,因为它进一步延迟了破坏。

The behavior you are seeing is the one mandated by the standard: temporaries are destroyed at the end of the full expression creating them.

Historically another behavior was seen (and is still available in some compilers): destruction at the end of the block. In your case it wouldn't have made a difference as it delays still further the destruction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文