Return value optimization and copy elision in C(C 中的返回值优化和复制省略)
问题描述
有些人不知道可以传递和返回结构体按 C 中的值.我的问题是关于编译器在 C 中返回结构时制作不必要的副本. GCC 等 C 编译器是否使用 返回值优化(RVO) 优化还是仅 C++ 的概念?我所读到的关于 RVO 和复制省略的所有内容都与 C++ 有关.
Some people are not aware that it's possible to pass and return structs by value in C. My question is about the compiler making unnecessary copies when returning structs in C. Do C compilers such as GCC use Return value optimization(RVO) optimization or is this a C++ only concept? Everything I have read about RVO and copy elision is in regards to C++.
让我们考虑一个例子.我目前正在 C 中实现 双双数据类型(或者更确切地说是 float-float 开始,因为我发现单元测试很容易).考虑以下代码.
Let's consider an example. I'm currently implementing a double-double data type in C (or rather float-float to start with because I find it easy to unit test). Consider the following code.
typedef struct {
float hi;
float lo;
} doublefloat;
doublefloat quick_two_sum(float a, float b) {
float s = a + b;
float e = b - (s - a);
return (doublefloat){s, e};
}
编译器会生成我返回的 doublefloat 值的临时副本还是可以省略临时副本?
Will the compiler make a temporary copy of the doublefloat value I return or can the temporary copy be elided?
C 中的命名返回值优化 (NRVO) 怎么样?我还有一个功能
What about named return value optimization (NRVO) in C? I have another function
doublefloat df64_add(doublefloat a, doublefloat b) {
doublefloat s, t;
s = two_sum(a.hi, b.hi);
t = two_sum(a.lo, b.lo);
s.lo += t.hi;
s = quick_two_sum(s.hi, s.lo);
s.lo += t.lo;
s = quick_two_sum(s.hi, s.lo);
return s;
}
在这种情况下,我将返回一个命名结构.这种情况下的临时副本可以省略吗?
In this case i'm returning a named struct. Can the temporary copy in this case be elided?
应该说明的是,这是 C 的一般问题,我在这里使用的代码示例只是示例(当我优化它时,无论如何我都会使用带有内在函数的 SIMD).我知道我可以查看汇编输出以了解编译器做了什么,但我认为这是一个有趣的问题.
It should be stated that this is a general question for C and that the code examples I have used here are only examples (when I optimize this I will be using SIMD with intrinsics anyway). I'm aware that I could look at the assembly output to see what the compiler does but I think this is an interesting question nevertheless.
推荐答案
RVO/NRVO 在 C 中的as-if"规则下是明确允许的.
RVO/NRVO are clearly allowed under the "as-if" rule in C.
在 C++ 中,您可以获得可观察到的副作用,因为您重载了构造函数、析构函数和/或赋值运算符以产生这些副作用(例如,当这些操作之一发生时打印出来),但在 C 中,您没有任何重载这些运算符的能力,并且内置的运算符没有可观察到的副作用.
In C++ you can get observable side-effects because you've overloaded the constructor, destructor, and/or assignment operator to give those side effects (e.g., print something out when one of those operations happens), but in C you don't have any ability to overload those operators, and the built-in ones have no observable side effects.
如果不重载它们,复制省略就不会产生可观察到的副作用,因此没有什么可以阻止编译器这样做.
Without overloading them, you get no observable side-effects from copy elision, and therefore nothing to stop a compiler from doing it.
这篇关于C 中的返回值优化和复制省略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C 中的返回值优化和复制省略
基础教程推荐
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- CString 到 char* 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 初始化列表*参数*评估顺序 2021-01-01
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
