假设我有以下函数来初始化数据结构:
void init_data(struct data *d) {
d->x = 5;
d->y = 10;
}
但是,使用以下代码:
struct data init_data(void) {
struct data d = { 5, 10 };
return d;
}
这不会因为复制省略而被优化掉,并且与前一版本一样高效吗?
我尝试在godbolt上进行一些测试以查看程序集是否相同,但在使用任何优化标记时,所有内容总是完全优化掉,没有任何内容,但是这样的内容:movabsq $42949672965, %rax
,我不确定在实际代码中是否会发生同样的情况。
我提供的第一个版本在C库中似乎很常见,我不明白为什么它们应该和RVO一样快,后者需要更少的代码。
答案 0 :(得分:0)
我提供的第一个版本似乎在C库中很常见,我不明白为什么它们应该同样快速 RVO,后者需要较少的代码。
首次如此普遍的主要原因是历史性的。从文字初始化结构的第二种方式不是标准的(好吧,它只是static
初始值设定项,而不是自动变量)并且它永远不允许在任务中使用(嗯,我是' ve没有检查最近标准的状态)甚至,在古代C中,一个简单的任务为:
struct A a, b;
...
a = b; /* this was not allowed a long time ago */
根本没被接受。
因此,为了能够在每个平台上编译代码,您必须编写旧方法,正常情况下,现代编译器允许您编译遗留代码,而相反(旧编译器接受新代码)是不可能的
这也适用于返回结构或按值传递它们。除了通常是资源的巨大浪费(看到整个结构被复制到堆栈中或复制回适当的地方,一旦函数返回,这很常见)旧的编译器不接受这些,所以为了便携,你必须避免使用这些结构。
最后一条评论:不要使用你的编译器来检查两个构造是否生成相同的代码,可能它会...但你会得到错误的假设,这是常见的,而你&# 39; ll遇到错误。另一种不同的实现可以(并且允许)进行不同的翻译并产生不同的代码。