首页 > 解决方案 > Execution order of operator new and argument of constructor

问题描述

Does C++ spec specify the order operator new and the constructor of A in new C(A()).
The g++ let the order be A() -> new -> C(), but clang++ let it be new -> A() -> C().
Is the difference caused by unspecified behavior?

g++ :7.4.0 clang++: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++language-lawyerc++17order-of-execution

解决方案


叮当是正确的。从 C++17 开始,执行顺序得到保证。[expr.new]/19

分配函数的调用在new-initializer中表达式的计算之前排序。

operator new(分配函数)应该首先被调用,然后是 new-initializer 中的表达式的评估(即A())。

在 C++17 之前,不保证顺序。[expr.new]/18 (C++14)

分配函数的调用相对于new-initializer中表达式的计算是不确定的。


似乎 gcc 不符合 C++17(及更高版本);在 C++2a 模式下使用 gcc10编译会得到相同的结果。


推荐阅读