Disabling g++'s return-value optimisation
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases. [Source: man gcc]
How to disable return value optimization in Visual Studio 2010?
You cannot. It is just that simple. RVO/NRVO is Standard, and your code should not depend on it not being present.
Impossible to disable return value optimization for std::string?
Return value optimization affects the local object (s
in your str_return
function). You never instrument that.
The string object itself manages dynamic memory and chooses to hand that managed memory over to the next string upon return. What you're instrumenting is that managed memory. Sensibly enough, that doesn't change.
If you really want to see the effect of RVO, instrument the local object:
#include <iostream>
#include <string>
void print_ptr(const std::string& s)
{
std::cout << "ptr: " << static_cast<const void *>(&s) << std::endl;
}
std::string str_return(const char* suffix)
{
std::string s("prefix");
s += " ";
s += suffix;
print_ptr(s);
return s;
}
int main()
{
std::string s = str_return("suffix");
print_ptr(s);
std::string t = str_return("suffix2");
print_ptr(t);
}
c++11 Return value optimization or move?
Use exclusively the first method:
Foo f()
{
Foo result;
mangle(result);
return result;
}
This will already allow the use of the move constructor, if one is available. In fact, a local variable can bind to an rvalue reference in a return
statement precisely when copy elision is allowed.
Your second version actively prohibits copy elision. The first version is universally better.
What are copy elision and return value optimization?
Introduction
For a technical overview - skip to this answer.
For common cases where copy elision occurs - skip to this answer.
Copy elision is an optimization implemented by most compilers to prevent extra (potentially expensive) copies in certain situations. It makes returning by value or pass-by-value feasible in practice (restrictions apply).
It's the only form of optimization that elides (ha!) the as-if rule - copy elision can be applied even if copying/moving the object has side-effects.
The following example taken from Wikipedia:
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C();
}
int main() {
std::cout << "Hello World!\n";
C obj = f();
}
Depending on the compiler & settings, the following outputs are all valid:
Hello World!
A copy was made.
A copy was made.
Hello World!
A copy was made.
Hello World!
This also means fewer objects can be created, so you also can't rely on a specific number of destructors being called. You shouldn't have critical logic inside copy/move-constructors or destructors, as you can't rely on them being called.
If a call to a copy or move constructor is elided, that constructor must still exist and must be accessible. This ensures that copy elision does not allow copying objects which are not normally copyable, e.g. because they have a private or deleted copy/move constructor.
C++17: As of C++17, Copy Elision is guaranteed when an object is returned directly:
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C(); //Definitely performs copy elision
}
C g() {
C c;
return c; //Maybe performs copy elision
}
int main() {
std::cout << "Hello World!\n";
C obj = f(); //Copy constructor isn't called
}
What is the magic in return value optimization on this?
Because you use C++17, which promises RVO, even you added -O0.
this maybe help
Is there a way to disable copy elision in c++ compiler
Pre C++ 17
A a3 = 0;
will call copy constructor unless copy is elided. Pass -fno-elide-constructors
flag
from C++17
, copy elision is guaranteed. So you will not see copy constructor getting called.
How to disable compiler optimizations in gcc?
The gcc option -O
enables different levels of optimization. Use -O0
to disable them and use -S
to output assembly. -O3
is the highest level of optimization.
Starting with gcc 4.8 the optimization level -Og
is available. It enables optimizations that do not interfere with debugging and is the recommended default for the standard edit-compile-debug cycle.
To change the dialect of the assembly to either intel or att use -masm=intel
or -masm=att
.
You can also enable certain optimizations manually with -fname
.
Have a look at the gcc manual for much more.
Related Topics
How to Create/Read/Write JSON Files in Qt5
What Use Are Const Pointers (As Opposed to Pointers to Const Objects)
C++11 Range-Based For-Loop Efficiency "Const Auto &I" Versus "Auto I"
Unresolved External Symbol "Public: Virtual Struct Qmetaobject Const * _Thiscall Parent
Manual for Cross-Compiling a C++ Application from Linux to Windows
Recursive Lambda Functions in C++14
What Is a Good Easy to Use Profiler for C++ on Linux
Is Gcc Std::Unordered_Map Implementation Slow? If So - Why
C++ How to Allocate Memory Dynamically on Stack
One Way of Eliminating C4251 Warning When Using Stl-Classes in the Dll-Interface
Differencebetween a .Cpp File and a .H File
Different Ways of Initializing an Object in C++
Iter_Swap() Versus Swap() -- What's the Difference
Templates: Template Function Not Playing Well with Class's Template Member Function
Simple Ipc Between C++ and Python (Cross Platform)
Converting Between C++ Std::Vector and C Array Without Copying
Serial Port (Rs -232) Connection in C++
Missing C++ Header <_Debug> After Updating Osx Command Line Tools 6.3