In the following code, are pS
and s.pS
guaranteed to be equal in the final line? In other words, in the statement S s = S();
, can I be sure that a temporary S
will not be constructed?
#include <iostream>
using namespace std;
struct S
{
S() { pS = this; }
S* pS;
};
int main()
{
S s = S();
S* pS = &s;
cout << pS << " " << s.pS << endl;
}
In every compiler I've tested this in pS == s.pS
, but I'm not sufficiently familiar with the standard to be able to satisfy myself that this is guaranteed.
NO
The compiler isn't obligated to do copy elision. The standard simply specifies that, [class.copy]:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...]
I can disable copy elision via -fno-elide-constructors
, and then the two pointers will definitely be different. For example:
$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930
And in the general case, if we add S(S&& ) = delete
, then the above code wouldn't even compile.
Most compilers performs what's called copy/move elision, which is specified by the C++ standard. But it is not guaranteed. For example, you can compile with -fno-elide-constructors
in gcc and you'll see all constructors in all their glory.
Live example on Coliru
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With