In other words, is there relationships between -fno-elide-constructors
and -O..?
Yes there is a relationship, although a quite simple one: gcc will most likely elide constructors already at the -O0
level unless you explicitly disable it. See the example code at the bottom for proof.
It is tricky though, the compiler can do really nasty things, see RVO force compilation error on failure. The bottom line is: You always need to check the generated assembly to see what is really happening under the hood.
Please keep in mind (from Working Draft, Standard for Programming
Language C++, N3797 which is the closest approximation of C++14 that I could find):
12.8/31 When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. [...]
The code substantiating my statement:
#include <cstdio>
constexpr int size = 1024;
struct A { int array[size] = { 0 }; };
int main() {
A a = A();
std::printf("%d\n", a.array[size-1]);
}
With g++ -std=c++11 -Wall -O0 -S elide.cpp
, in the generated assembly code there is only a single
call A::A()
However, with g++ -std=c++11 -Wall -O0 -fno-elide-constructors -S elide.cpp
I get:
call A::A()
[...]
call A::A(A&&)
Even if you disable optimizations with -O0
, you still have to disable elision additionally if you need it to be disabled for some reason.