我可能会问一个愚蠢的问题,但我查看了RVO here的维基百科页面,并且不禁想知道这种行为是否错误。我在我的机器上尝试了它,尽管优化水平,但RVO完全被踢了。如果在构造函数中实际发生了 BIG ,该怎么办?我知道它不应该,但如果呢?我无法理解为什么在构造函数中存在副作用时仍会发生RVO。
编辑:-fno-elide-constructors
似乎停止了RVO。但问题仍然存在。
EDIT2:更严重的是,有多少人知道这样的事情?它可能在标准中,但它仍然是一个非常难看的功能,因为我看到它。至少编译器应该默认禁用它,并为知道这一点的人提供一个开关。 :)
编辑3:我仍然坚持认为这真的很糟糕。 :)。我不认为我知道任何其他语言约束直接违背语言的语法。其他所有东西都会抛出编译器或链接器错误吗?
答案 0 :(得分:20)
标准要求关注程序的 可观察状态 的操作不得优化, 除了复制构造 强>在某些情况下。您不能依赖复制构造函数来执行,即使它们具有您期望看到的副作用(例如,控制台输出)。
答案 1 :(得分:13)
正如在其他答案中所说的那样,允许编译器优化掉甚至非平凡的拷贝构造函数和赋值运算符。
12.8.15
当满足某些条件时,允许实现省略类对象的复制构造,即使是 对象的复制构造函数和/或析构函数具有副作用。在这种情况下,实施处理 省略的复制操作的源和目标只是两种不同的引用同一对象的方式,而且 该对象的破坏发生在两个对象在没有被破坏的情况下被破坏的时间 优化。在下列情况下允许复制操作的这种省略(可以合并 消除多份副本):
- 在具有类返回类型的函数的return语句中,当表达式是非易失性的名称时 具有与函数返回类型相同的cv-unqualified类型的自动对象,可以省略复制操作 通过将自动对象直接构造到函数的返回值
中- 当一个尚未绑定到引用(12.2)的临时类对象被复制到一个类对象时 在相同的cv-unqualified类型中,可以通过直接构造临时对象来省略复制操作 省略副本的目标
答案 2 :(得分:7)
定义“错误”。 C ++语言明确允许这种优化,即使它是可观察的。如果你的程序的行为取决于具体的实现,那么很遗憾你没有使用ISO C ++,而是使用某种方言。