简体   繁体   中英

In S s = S() is it guaranteed that no temporary will be created?

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

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; .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM