在 S s = S() 中是否保证不会创建临时文件?
In S s = S() is it guaranteed that no temporary will be created?
在下面的代码中,最后一行的pS
和s.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
中对此进行了测试,但我对标准还不够熟悉,无法让自己确信这是有保证的。
大多数编译器执行所谓的 copy/move elision,这是由 C++ 标准指定的。但这并不能保证。例如,您可以在 gcc 中使用 -fno-elide-constructors
进行编译,并且您会看到 所有 构造函数的全部荣耀。
否
编译器没有义务进行复制省略。该标准简单地规定,[class.copy]:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...]
我可以通过-fno-elide-constructors
禁用复制省略,然后两个指针肯定会不同。例如:
$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930
而且在一般情况下,如果我们添加S(S&& ) = delete
,那么上面的代码甚至无法编译。
不保证不会有临时的。但是三大编译器会优化它(即使使用 -O0
开关)。
为了保证没有临时的,只写:
int main()
{
// ...
S s{};
// ...
}
或者干脆 S s;
.
在下面的代码中,最后一行的pS
和s.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
中对此进行了测试,但我对标准还不够熟悉,无法让自己确信这是有保证的。
大多数编译器执行所谓的 copy/move elision,这是由 C++ 标准指定的。但这并不能保证。例如,您可以在 gcc 中使用 -fno-elide-constructors
进行编译,并且您会看到 所有 构造函数的全部荣耀。
否
编译器没有义务进行复制省略。该标准简单地规定,[class.copy]:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...]
我可以通过-fno-elide-constructors
禁用复制省略,然后两个指针肯定会不同。例如:
$g++ -std=c++11 -Wall -pedantic -fno-elide-constructors -Wall -Wextra main.cpp && ./a.out
0x7fff5a598920 0x7fff5a598930
而且在一般情况下,如果我们添加S(S&& ) = delete
,那么上面的代码甚至无法编译。
不保证不会有临时的。但是三大编译器会优化它(即使使用 -O0
开关)。
为了保证没有临时的,只写:
int main()
{
// ...
S s{};
// ...
}
或者干脆 S s;
.