编译器是否会优化返回具有固定大小数组的结构的函数?

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变量,或将填补第一ffunc,然后所有值从复制fff

如何检查是否执行了优化?

eer*_*ika 7

我的回答适用于c ++.

编译器会执行某种优化(即TCO)吗?

通过TCO你的意思是"尾部呼叫优化"?该函数最后没有进行函数调用(尾调用,如果你愿意的话),因此优化不适用.

由于命名返回值优化,编译器可以 将复制从返回值中删除到临时值.临时的复制初始化也可以省略.


如何检查是否执行了优化?

通过读取生成的汇编代码.

如果你不能阅读汇编,另一种方法是添加复制和移动有副作用的构造函数,并观察是否会出现这些副作用.但是,修改程序可能会影响编译器是否决定优化(但不需要副作用来防止复制省略).


如果您不想依赖优化,则应通过引用(c中的指针)显式地将退出对象传递给函数,并在适当位置对其进行修改.


复制省略的标准参考[class.copy]§31(现行标准草案)

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用.[...]

该部分描述了在这种情况下满足的标准.该报价是根据2016-04-07的标准文件草案生成的.编号可能因标准文档的不同版本而异,并且规则略有变化.引用的部分自c ++ 03以来一直没有变化,其中该部分是[class.copy]§15.

  • @Olaf copy elision有一个特殊的例外,可以忽略as-if规则.我不知道c,所以我添加了一个免责声明(尽管复制除了复制本身之外不能有副作用,无论如何,可以吗?). (4认同)