返回值优化(RVO)是不是一个bug?

nak*_*iya 7 c++ return-value-optimization

我可能会问一个愚蠢的问题,但我在这里查看了RVO的维基百科页面,并且无法停止想知道这种行为是否错误.我在我的机器上尝试了它,尽管优化水平,RVO仍然完全被踢了.如果确实有一些的构造happenning?我知道它不应该,但如果呢?我无法理解为什么在构造函数中存在副作用时仍会发生RVO.

编辑:-fno-elide-constructors似乎停止RVO.但问题仍然存在.

编辑2:更严重的是,有多少人知道这样的事情?它可能在标准中,但它仍然是一个非常难看的功能,因为我看到它.至少编译器应该默认禁用它,并为知道这一点的人提供一个开关.:)

编辑3:我仍然坚持认为这真的很糟糕.:).我不认为我知道任何其他语言约束直接违背语言的语法.其他一切都会引发编译器或链接器错误吗?

sbi*_*sbi 20

标准规定,除了在某些情况下的复制结构外,不得优化掉与程序可观察状态有关的操作.您不能依赖复制构造函数来执行,即使它们具有您期望看到的副作用(例如,控制台输出).

  • @nakiya:在`shared_ptr`的情况下,创建一个几乎立即被销毁的额外临时对象具有递增然后递减引用计数的效果,因此无论优化是否发生,引用计数都会相同. (5认同)
  • @nakiya:许多更高级的C++书籍中都有返回值优化.我冒昧地说复制构造函数有副作用的程序可能是错误的,无论RVO是否生效,因为我认为这是一个真正的坏主意. (4认同)
  • @nakiya:好吧,如果复制构造函数被优化掉,那么这是因为副本被优化掉了,而且根本就没有创建.然后没有增加引用计数器(事实上,它是唯一正确的行为).;) (3认同)
  • @nakiya:如果开发人员不了解它们,C++中的很多东西都会导致错误.但是如果你把你的拷贝构造函数写成"明智地",也就是说,它构造一个副本,而不是其他任何东西,那么它*只在有和没有RVO的情况下工作*. (3认同)

Der*_*hen 13

正如在其他答案中所说的那样,允许编译器优化掉甚至非平凡的拷贝构造函数和赋值运算符.

15年8月12日

当满足某些条件时,允许实现省略类对象的复制结构,即使该对象的复制构造函数和/或析构函数具有副作用.在这种情况下,实现将省略的复制操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象在没有被销毁的情况下的后期.优化.在以下情况下允许复制操作的这种省略(可以组合以消除多个副本):

- 在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象的名称时,通过构造自动化可以省略复制操作对象直接进入函数的返回值

- 当一个未绑定到引用(12.2)的临时类对象被复制到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到省略的目标中来省略复制操作复制

  • @MattJoiner,你可以期待它你喜欢但你不会得到它.有没有标准的在线(法律)HTML副本,这是一个受版权保护的文件只能在纸张或PDF格式正式发布,所以这将是困难和/或调皮的方便的形式链接到一个特定的段落.[这里](https://github.com/cplusplus/draft/blob/d8fb8cf16dd05f711d33b3749a757d69068e45ef/source/special.tex#L2957)是那款LaTeX的来源,最终标准发布不久之前,但它是不是非常方便阅读胶乳. (3认同)

Hel*_*hne 8

定义"错误".C++语言明确允许这种优化,即使它是可观察的.如果程序的行为取决于具体的实现,那么遗憾的是你没有使用ISO C++,而是使用某种方言.