Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return value optimization and copy elision in 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++.

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}; } 

Will the compiler make a temporary copy of the doublefloat value I return or can the temporary copy be elided?

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?

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.

like image 653
Z boson Avatar asked May 04 '15 15:05

Z boson


People also ask

Does C have return value optimization?

> Note also that C doesn't have return-value-optimization, hence all your struct-returning functions will cause a call to memcpy (won't happen when compiled in C++ mode of course).

How does return value optimization work?

In the context of the C++ programming language, return value optimization (RVO) is a compiler optimization that involves eliminating the temporary object created to hold a function's return value. RVO is allowed to change the observable behaviour of the resulting program by the C++ standard.

How is copy elision implemented?

When copy elision occurs, the implementation treats the source and target of the omitted copy/move (since C++11) operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the ...

What is named return value optimization?

(Named) Return value optimization is a common form of copy elision. It refers to the situation where an object returned by value from a method has its copy elided. The example set forth in the standard illustrates named return value optimization, since the object is named.


1 Answers

RVO/NRVO are clearly allowed under the "as-if" rule in 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.

like image 152
Jerry Coffin Avatar answered Oct 07 '22 18:10

Jerry Coffin