编译器是否会优化返回具有固定大小数组的结构的函数?
假设我在C/C++中有一个具有固定大小的数组成员的struct
,例如:
#define SIZE 10000
struct foo{
int vector_i[SIZE];
float vector_f[SIZE];
};
我想创建一个函数,该函数将返回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;
}
如果我使用:
调用函数foo ff = func(1,1.1);
编译器是否会执行某种优化(即总拥有成本)?
可执行文件是直接填充ff
变量,还是先填充func
中的f
,然后复制f
到ff
中的所有值?
如何检查是否执行了优化?
解决方案
我的答案适用于C++。
编译器是否会执行某种优化(即总拥有成本)?
您所说的TCO是指"尾部呼叫优化"吗?该函数不会在末尾进行函数调用(如果愿意,可以称为尾部调用),因此不会应用优化。
由于命名返回值优化,编译器可以elide将返回值复制到临时。还可以避免从临时数据库进行复制初始化。
如何检查是否执行了优化?
通过读取生成的汇编代码。
如果您不能读取程序集,另一种方法是添加有副作用的复制和移动构造函数,并观察这些副作用是否发生。但是,修改程序可能会影响编译器是否决定进行优化(但不需要副作用来防止复制遗漏)。
如果不想依赖优化,则应通过引用(c中的指针)将退出对象显式传递给函数,并就地修改它。
复制删除的标准参考[class.copy] §31 (current standard draft)
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用。[...]本节介绍了在本例中满足的条件。该报价是根据2016-04-07年4月4日的标准文件草稿生成的。不同版本的标准文件的编号可能会有所不同,规则也略有变化。引用部分自c++03起一直未更改,其中部分为[类.副本]§15。
相关文章