Copy elision (also known as copy omission) is a compiler optimization method that prevents objects from being duplicated or copied. It makes ‘returning by value’ or ‘pass-by-value’ feasible in practice. In simple terms, the compiler prevents the making of extra copies which results in saving space and better the program complexity(both time and space); Hence making the code more optimized. Nowadays, almost every compiler uses it.
This also means fewer objects can be created, so you also can’t rely on a specific number of destructors being called. Or we can conclude that the compiler gets some special power in which they can print according to their utmost feasibility.
Example:
C++
#include <iostream>
using namespace std;
class GFG {
public :
GFG() { cout << "GeeksforGeeks" ; }
GFG( const GFG&)
{
cout << " GeeksforGeeks Copy Constructor" ;
}
};
GFG func()
{
return GFG();
}
int main()
{
GFG G;
return 0;
}
|
Output:
GeeksforGeeks
Now it is on the compiler to decide what it wants to print, it could either print the above output or it could print case 1 or case 2 below, and this is what Return Value Optimization is. In simple words, RVO is a technique that gives the compiler some additional power to terminate the temporary object created which results in changing the observable behavior/characteristics of the final program.
Case 1:
GeeksforGeeks
GeeksforGeeks Copy Constructor
GeeksforGeeks Copy Constructor
Case 2:
GeeksforGeeks
GeeksforGeeks Copy Constructor
These cases will appear because we used the “-fno-elide-constructors” flag which mandatorily calls copy constructor.
Example:
C++
#include <iostream>
using namespace std;
class GFG {
public :
GFG() { cout << "GeeksforGeeks" ; }
GFG( const GFG&)
{
cout << " GeeksforGeeks Copy Constructor" ;
}
};
GFG func()
{
GFG G;
return G;
}
int main()
{
GFG G = func();
return 0;
}
|
Output:
GeeksforGeeks
In NRVO there won’t be any other cases as we explicitly called it the instance of an object which resulted in calling only once. So there won’t be a case of the “-fno-elide-constructors” flag now.
Example:
C++
#include <iostream>
using namespace std;
class B {
public :
B( const char * str = "\0" )
{
cout << "Constructor called" << endl;
}
B( const B& b)
{
cout << "Copy constructor called" << endl;
}
};
int main()
{
B ob;
return 0;
}
|
Output:
Constructor called
Why copy constructor is not called?
According to theory, when the object “ob” is being constructed, one argument constructor is used to convert “copy me” to a temporary object & that temporary object is copied to the object “ob”. So the statement
B ob = "copy me"; // Also RVO form to represent
should be broken down by the compiler as:
B ob = B("copy me"); // Also NRVO form to represent
However, most C++ compilers avoid such overheads of creating a temporary object & then copying it.
The modern compilers break down the statement
B ob = "copy me"; //copy initialization
as
B ob("copy me"); //direct initialization
and thus eliding call to copy constructor.
However, if we still want to ensure that the compiler doesn’t elide the call to copy constructor [disable the copy elision], we can compile the program using the “-fno-elide-constructors” option with C++
Output:
GEEKSFORGEEKS:~$ g++ copy_elision.cpp -fno-elide-constructors
GEEKSFORGEEKS:~$ ./a.out /\---This is a flag which calls copy constructor statement and
Constructor called reduce compiler's optimiziblity
Copy constructor called
If the “-fno-elide-constructors” option is used, a first default constructor is called to create a temporary object, then the copy constructor is called to copy the temporary object to ob.
Difference Between NRO and RVO
NRVO
|
RVO
|
It is known as Named Return Value Optimization |
It is known as Return Value Optimization |
It is neither guaranteed nor mandatory to be called |
It is guaranteed to be called in a modern compiler program |
Instead of creating a local return object and then moving/copying it in place of the function call, NRVO instantly creates it in the called place.
|
Instead, the returned object is constructed in place of the function call. It does not allow the creation of a local object that is used as a return value.
|
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
16 Mar, 2023
Like Article
Save Article