编译器优化 [英] compiler optimization
问题描述
所以我有一个问题。 :)
你能告诉我下面代码应该产生的输出吗?
So I have a question for you. :) Can you tell me the output the following code should produce?
#include <iostream>
struct Optimized
{
Optimized() { std::cout << "ctor" << std::endl; }
~Optimized() { std::cout << "dtor" << std::endl; }
Optimized(const Optimized& copy) { std::cout << "copy ctor" << std::endl; }
Optimized(Optimized&& move) { std::cout << "move ctor" << std::endl; }
const Optimized& operator=(const Optimized& rhs) { std::cout << "assignment operator" << std::endl; return *this; }
Optimized& operator=(Optimized&& lhs) { std::cout << "move assignment operator" << std::endl; return *this; }
};
Optimized TestFunction()
{
Optimized a;
Optimized b = a;
return b;
}
int main(int argc, char* argv[])
{
Optimized test = TestFunction();
return 0;
}
我的第一个回答是:
- ctor
- 复制ctor
- 移动ctor
- dtor
- dtor
- dtor
- ctor
- copy ctor
- move ctor
- dtor
- dtor
- dtor
IS为true,但仅在编译器优化处于关闭状态。当优化打开时,输出完全不同。启用优化后,输出为:
and it IS true, but only if compiler optimization is turned off. When optimization is turned ON then the output is entirely different. With optimization turned on, the output is:
- ctor
- 复制ctor
- dtor
- dtor
- ctor
- copy ctor
- dtor
- dtor
通过编译器优化,测试变量返回变量。
With compiler optimization, the test variable is the return variable.
我的问题是,什么条件会导致这种方式不能优化?
My question is, what conditions would cause this to not be optimized this way?
我一直被教导,返回一个结构/类,导致额外的复制构造函数可以更好地通过作为参考传递进行优化,但编译器正在为我做这个。
I have always been taught that returning a struct/class which results in extra copy constructors could better be optimized by being passed in as a reference but the compiler is doing that for me. So is return a structure still considered bad form?
推荐答案
这被称为复制Elision
标准特别允许优化,只要它可以复制/移动(即,该方法是声明和可访问)。
The optimization is specifically allowed by the Standard, as long as it would be possible to copy/move (ie, the method is declared and accessible).
在这种情况下,编译器中的实现通常称为返回值优化。有两种变体:
The implementation in a compiler is generally referred to, in this case, as Return Value Optimization. There are two variations:
- RVO :当您返回一个临时(
当您返回一个名称为
的对象时,Named会返回aa+ someString; ) -
- RVO: when you return a temporary (
return "aa" + someString;
) - NRVO: N for Named, when you return an object that has a name
两者都由主要编译器实现,但后者只能在较高的优化级别启动,因为它更难以检测。
Both are implemented by major compilers, but the latter may kick in only at higher optimization levels as it is more difficult to detect.
因此,要回答关于返回结构体的问题:我会推荐它。考虑:
Therefore, to answer your question about returning structs: I would recommend it. Consider:
// Bad
Foo foo;
bar(foo);
-- foo can be modified here
// Good
Foo const foo = bar();
后者不仅更清楚,还允许 const
enforcement!
The latter is not only clearer, it also allows const
enforcement!
这篇关于编译器优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!