La spécification C++ spécifie-t-elle l'ordre operator new
Et le constructeur de A
dans new C(A())
.
Le g ++ laisse l'ordre être A()
-> new
-> C()
, mais clang ++ le laisse être new
-> A()
-> C()
.
La différence est-elle causée par un comportement non spécifié?
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());
}
Clang a raison. Depuis C++ 17, l'ordre d'exécution est garanti. [expr.new]/19
L'invocation de la fonction d'allocation est séquencée avant les évaluations d'expressions dans le new-initializer .
operator new
(La fonction d'allocation) est supposé être appelé en premier, puis l'évaluation de l'expression dans le nouveau initialiseur (c'est-à-dire A()
).
Avant C++ 17, la commande n'est pas garantie. [expr.new]/18 (C++ 14)
L'invocation de la fonction d'allocation est séquencée de façon indéterminée par rapport aux évaluations d'expressions dans le new-initializer .
Il semble que gcc ne soit pas conforme à C++ 17 (et versions ultérieures); la compilation avec gcc10 en mode C++ 2a donne le même résultat.