问题
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.
回答1:
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.
回答2:
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
回答3:
There is no guarantee that there will be no temporary. But the Big Three compilers will optimize it out (even with the -O0
switch).
To guarantee no temporary at all just write:
int main()
{
// ...
S s{};
// ...
}
Or simply S s;
.
来源:https://stackoverflow.com/questions/33086346/in-s-s-s-is-it-guaranteed-that-no-temporary-will-be-created