zti*_*tik 8 c c++ struct return-value return-value-optimization
假设我有一个struct带有固定大小数组成员的C/C++,例如:
#define SIZE 10000
struct foo{
int vector_i[SIZE];
float vector_f[SIZE];
};
Run Code Online (Sandbox Code Playgroud)
我想创建一个函数,它将返回一个实例foo,如:
foo func(int value_i, float value_f){
int i;
foo f;
for(i=0;i<SIZE;i++) f.vector_i[i] = value_i;
for(i=0;i<SIZE;i++) f.vector_f[i] = value_f;
return f;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用以下方法调用函数:
foo ff = func(1,1.1);
Run Code Online (Sandbox Code Playgroud)
编译器会执行某种优化(即TCO)吗?
将可执行填写直接ff变量,或将填补第一f的func,然后所有值从复制f到ff?
如何检查是否执行了优化?
我的回答适用于c ++.
编译器会执行某种优化(即TCO)吗?
通过TCO你的意思是"尾部呼叫优化"?该函数最后没有进行函数调用(尾调用,如果你愿意的话),因此优化不适用.
由于命名返回值优化,编译器可以 将复制从返回值中删除到临时值.临时的复制初始化也可以省略.
如何检查是否执行了优化?
通过读取生成的汇编代码.
如果你不能阅读汇编,另一种方法是添加复制和移动有副作用的构造函数,并观察是否会出现这些副作用.但是,修改程序可能会影响编译器是否决定优化(但不需要副作用来防止复制省略).
如果您不想依赖优化,则应通过引用(c中的指针)显式地将退出对象传递给函数,并在适当位置对其进行修改.
复制省略的标准参考[class.copy]§31(现行标准草案)
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用.[...]
该部分描述了在这种情况下满足的标准.该报价是根据2016-04-07的标准文件草案生成的.编号可能因标准文档的不同版本而异,并且规则略有变化.引用的部分自c ++ 03以来一直没有变化,其中该部分是[class.copy]§15.