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.