在S s = S()中,是否保证不会创建临时值?

时间:2015-10-12 16:52:31

标签: c++ constructor language-lawyer temporary

在以下代码中,pSs.pS在最后一行中保证相等吗?换句话说,在S s = S();语句中,我可以确定不会构建临时S吗?

#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;
}

在每个编译器中我都在pS == s.pS中对此进行了测试,但我对标准不够熟悉,无法确保这一点得到保证。

3 个答案:

答案 0 :(得分:16)

编译器不义务进行复制省略。标准只是指定[class.copy]:

  

当满足某些条件时,允许实施 省略类对象的复制/移动构造[...]

我可以通过-fno-elide-constructors禁用复制省略,然后两个指针肯定会有所不同。例如:

$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930

在一般情况下,如果我们添加S(S&& ) = delete,那么上面的代码甚至都不会编译。

答案 1 :(得分:11)

大多数编译器执行名为copy/move elision的内容,这是由C ++标准指定的。但它不能保证。例如,您可以使用gcc中的-fno-elide-constructors进行编译,并且您将在所有荣耀中看到所有构造函数。

Live example on Coliru

答案 2 :(得分:5)

无法保证不会有临时性。但三巨头编译器会优化它(即使使用-O0开关)。

为了保证没有临时性,只需写下:

int main()
{
  // ...
  S s{};
  // ...
}

或只是S s;