运算符new的执行顺序和构造函数的参数
Posted
技术标签:
【中文标题】运算符new的执行顺序和构造函数的参数【英文标题】:Execution order of operator new and argument of constructor 【发布时间】:2020-04-14 13:53:53 【问题描述】:C++ 规范是否在new C(A())
中指定了operator new
的顺序和A
的构造函数。
g++ 让顺序为 A()
-> new
-> C()
,但 clang++ 让它为 new
-> A()
-> C()
。
差异是由未指定的行为引起的吗?
g++ :7.4.0 铿锵++:10.0.0
#include <iostream>
#include <cstdlib>
struct A
A()
std::cout << "call A()\n";
;
struct C
C(A)
std::cout << "call S()\n";
void *operator new(size_t s)
std::cout << "call new()\n";
return malloc(s);
;
int main()
void *p = new C(A());
【问题讨论】:
您是使用 C++17、C++14 还是之前的版本构建? 两个注意事项:你用“C”标记了这个,这清楚地表明你没有阅读该标记的描述。别。现在,您询问“未定义的行为”(UB)。这是 C++ 标准使用的一个术语,用于标记任何事情都可能发生并且应该避免的事情。还有“未指定的行为”,这可能更接近您所追求的,因为代码在技术上很好并且不会导致 UB。 @Ulrich Eckhardt 谢谢你的建议。我把两者混在一起了。 【参考方案1】:Clang 是正确的。从 C++17 开始,执行顺序得到保证。 [expr.new]/19
分配函数的调用在new-initializer中的表达式计算之前排序。
operator new
(分配函数)应该首先被调用,然后是 new-initializer 中表达式的求值(即A()
)。
在 C++17 之前,不保证顺序。 [expr.new]/18 (C++14)
分配函数的调用相对于new-initializer 中表达式的求值是不确定的。
gcc 似乎不符合 C++17(及更高版本);使用gcc10 in C++2a mode 编译会得到相同的结果。
【讨论】:
以上是关于运算符new的执行顺序和构造函数的参数的主要内容,如果未能解决你的问题,请参考以下文章