【问题标题】:Does "Return value optimization" cause undefined behavior?“返回值优化”会导致未定义的行为吗?
【发布时间】:2010-02-24 05:42:31
【问题描述】:

阅读this Wikipedia 文章,其中一位回复者指出了以下问题:

C++ Copy constructor, temporaries and copy semantics

我遇到了这条线

根据编译器和编译器的设置,生成的程序可能会显示以下任何输出:

这不符合未定义的行为吗?我知道这篇文章说Depending on the compiler and settings,但我只是想澄清一下。

【问题讨论】:

  • 有实现定义,其中编译器实现者必须记录行为,然后这里未指定,这意味着只要“可观察行为”保持不变,编译器就可以做任何它想做的事情。然后是未定义的行为,这意味着您在程序中进入了不再定义其执行的状态。 RVO 是一种允许改变可观察行为的情况。

标签: c++ return-value-optimization


【解决方案1】:

不,这不是未定义的行为。未定义的行为在标准中有一个特定的定义(主要是:“行为,例如在使用错误的程序构造或错误数据时可能出现,本国际标准对此没有要求。”)在这种情况下,行为是未指定的,但不是未定义的。

不同之处在于,任何未定义行为的执行都会使程序的所有行为未定义(即任何事情都可能发生)。对于这种特殊的未指定行为,只能发生以下两种情况之一:复制构造函数执行,或者不执行。

【讨论】:

  • 我记得刚开始时我很困惑:未定义、未指定和实现定义。很好很简洁的解释。
【解决方案2】:

没有。该行为被定义为列表中的输出之一。未定义的行为包括恶魔飞出你的鼻子。

见:Nasal Demons

【讨论】:

    【解决方案3】:

    undefined behaviorimplementation defined behavior 完全不同,这就是这里所涉及的。

    【讨论】:

    • 它并没有真正定义实现——这需要实现来记录发生的事情,在这种情况下不需要。
    【解决方案4】:

    取决于未定义的含义。我相信其他人在这里所说的 - 根据标准文档使用的定义。但我也知道,当有人说“这个或那个,我不会告诉你哪个”时,我认为这是未定义的行为。

    不过,这没什么大不了的,因为它永远不会导致错误。当你定义某些方法时,你应该按照特定的约定来定义它们——这是你、编译器和将使用和维护你的代码的人之间的一种隐式契约。

    在这种情况下,无论您获得复制构造等还是优化的行为,预期效果都是一样的——调用者收到想要的值。如果您的复制构造函数正在打印“Hello World!”或者有其他不适当的副作用,它没有实现构造函数的预期行为,所以你违反合同是你的错。

    【讨论】:

    • +1 表示 副作用 可能由于此优化而无法静默执行 :) 如果它是您急切关注的打印语句终端,你可以抓住它;而更无声的事情,比如在构造发生时将消息传递给另一个对象,则不会发生并且难以捕捉。
    • 那么我可以从中推断出,无论构造函数的类型如何(默认、复制等),除了初始化成员之外,我不应该做任何特定的事情吗?
    • @legends2k:是的。该标准允许在从函数返回时省略复制构造函数调用,这意味着您的代码不应尝试依赖复制构造函数中的副作用。
    • 不正确。除了构造对象之外,它不应该做任何事情,这并不完全相同。例如,对象可能拥有存在于某个外部容器中的数据 - 例如。自定义分配。改变是副作用吗?严格来说是的,但在实践中,也许不是。然而,很难表达这些条件——主观上是关于将“什么”与“如何”分开,但如果应用程序允许用户报告/配置一些“如何”作为“什么”的一部分,那就没问题了。是的 - 我认为这绝对是可能的。部分。可能。清除吗?
    猜你喜欢
    • 2014-08-11
    • 2016-09-04
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 2016-02-17
    • 2022-11-16
    相关资源
    最近更新 更多