Ordine di esecuzione dell'operatore nuovo e argomento del costruttore


9

Le specifiche C ++ specificano l'ordine operator newe il costruttore di Ain new C(A()).
Il g ++ lascia che l'ordine sia A()-> new-> C(), ma clang ++ lascia che sia new-> A()-> C().
La differenza è causata da un comportamento non specificato?

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());
}

3
Stai costruendo come C ++ 17, C ++ 14 o precedenti?
StoryTeller - Unslander Monica il

4
Due note: l'hai taggato con "C", che mostra chiaramente che non hai letto la descrizione di quel tag. Non farlo. Ora, chiedi del "comportamento indefinito" (UB). Questo è un termine usato dallo standard C ++ per indicare cose in cui tutto può succedere e che dovrebbero essere evitate. Esiste anche un "comportamento non specificato", che è probabilmente più vicino a quello che stai cercando, perché il codice è tecnicamente valido e non causa UB.
Ulrich Eckhardt il

1
@Ulrich Eckhardt Grazie per il tuo suggerimento. Ho confuso i due.
Eddie Kuo,

Risposte:


11

Clang è corretto. Dal C ++ 17 l'ordine di esecuzione è garantito. [expr.new] / 19

L'invocazione della funzione di allocazione viene eseguita in sequenza prima delle valutazioni delle espressioni nel nuovo inizializzatore .

operator new(la funzione di allocazione) dovrebbe prima essere invocata, quindi la valutazione dell'espressione nel nuovo inizializzatore (cioè A()).

Prima di C ++ 17, l'ordine non è garantito. [expr.new] / 18 (C ++ 14)

L'invocazione della funzione di allocazione è indeterminata in sequenza rispetto alle valutazioni delle espressioni nel nuovo inizializzatore .


Sembra che gcc non sia conforme a C ++ 17 (e versioni successive); la compilazione con gcc10 in modalità C ++ 2a fornisce lo stesso risultato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.