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

橙三吉。 提交于 2020-01-14 07:19:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!