Czy specyfikacja C ++ określa kolejność operator new
i konstruktor A
w new C(A())
.
G ++ niech kolejność będzie A()
-> new
-> C()
, ale clang ++ niech będzie new
-> A()
-> C()
.
Czy różnica jest spowodowana nieokreślonym zachowaniem?
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-lawyer
c++17
order-of-execution
Eddie Kuo
źródło
źródło
Odpowiedzi:
Clang ma rację. Od wersji C ++ 17 kolejność wykonania jest gwarantowana. [expr.new] / 19
operator new
(funkcja alokacji) powinna być najpierw wywołana, a następnie ocena wyrażenia w nowym inicjalizatorze (tjA()
.).Przed wersją C ++ 17 zamówienie nie jest gwarantowane. [expr.new] / 18 (C ++ 14)
Wygląda na to, że gcc nie jest zgodne z C ++ 17 (i nowszymi); kompilacja z gcc10 w trybie C ++ 2a daje ten sam wynik.
źródło