Domanda

Questo mi ha fatto pensare:

class X;

void foo(X* p)
{
    delete p;
}

Come possiamo delete p se non abbiamo nemmeno sapere se X ha distruttore visibile? g ++ 4.5.1 dà tre avvertimenti:

warning: possible problem detected in invocation of delete operator:
warning: 'p' has incomplete type
warning: forward declaration of 'struct X'

E poi si dice:

  

Nota: né il distruttore, né l'operatore specifica classe di eliminazione   sarà chiamato, anche se sono dichiarati quando la classe è definita.

Wow ... sono compilatori necessari per diagnosticare questa situazione come g ++ fa? O è un comportamento indefinito?

È stato utile?

Soluzione

Dalla serie [expr.delete]:

  

Se l'essere oggetto eliminato ha   tipo di classe incompleta al punto di   la cancellazione e la classe completa ha un   non banale distruttore o un   funzione deallocazione, il comportamento è   non definito.

Quindi, è UB se c'è roba banale da fare, ed è ok se non c'è. Avvertenze non sono neccessary per UB.

Altri suggerimenti

Si tratta di un comportamento indefinito.

Tuttavia, è possibile effettuare il check-compilatore per i tipi incompleti, come spinta:

// verify that types are complete for increased safety

template<class T> inline void checked_delete(T * x)
{
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
}

L'applicazione di sizeof a un tipo incompleto dovrebbe far scattare un errore, e suppongo che passa se con qualche compilatore, quindi un array di dimensione negativa farebbe scattare un errore.

È comportamento indefinito, e un Gotcha comune quando attuazione del modello Pimpl. Al meglio della mia conoscenza, semplicemente non c'è cosa come un avvertimento che il compilatore è tenuto ad emettere. Avvertimenti sono elettive; Sono lì perché lo scrittore compilatore pensato che sarebbe utile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top