Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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());
}
like image 494
eddie kuo Avatar asked Feb 03 '23 16:02

eddie kuo


1 Answers

Clang is correct. Since C++17 the execution order is guaranteed. [expr.new]/19

The invocation of the allocation function is sequenced before the evaluations of expressions in the new-initializer.

operator new (the allocation function) is supposed to be invoked firstly, then the evaluation of expression in the new-initializer (i.e. A()).

Before C++17, the order is not guaranteed. [expr.new]/18 (C++14)

The invocation of the allocation function is indeterminately sequenced with respect to the evaluations of expressions in the new-initializer.


It seems gcc isn't conforming to C++17 (and later); compiling with gcc10 in C++2a mode gives the same result.

like image 180
songyuanyao Avatar answered May 14 '23 22:05

songyuanyao