Frage

Dieses hat mich denken:

class X;

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

Wie können wir delete p, wenn wir nicht einmal wissen, ob X sichtbar destructor hat? g ++ 4.5.1 gibt drei Warnungen:

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

Und dann heißt es:

  

Hinweis: weder der Destruktor noch der klassenspezifische Operator löschen   aufgerufen werden, auch wenn sie deklariert werden, wenn die Klasse definiert ist.

Wow ... sind Compiler erforderlich, um diese Situation wie g zu diagnostizieren ++ tut? Oder ist es nicht definiertes Verhalten?

War es hilfreich?

Lösung

Aus dem Standard [expr.delete]:

  

Wenn das Objekt, das gelöscht hat   unvollständiger Klassentyp an der Stelle der   Löschen und die komplette Klasse hat eine   nicht-triviale destructor oder   Freigabe-Funktion ist das Verhalten   nicht definiert.

Es ist UB Also, wenn es nicht-triviale Dinge zu tun, und es ist in Ordnung, wenn es nicht ist. Warnungen sind nicht notwendig für UB.

Andere Tipps

Es ist nicht definiertes Verhalten.

Sie können jedoch die Compiler-Check für unvollständige Typen machen, wie boost:

// 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;
}

Die Anwendung sizeof auf einen unvollständigen Typen sollte einen Fehler auslösen, und ich nehme an, wenn das mit einigen Compiler übergibt, dann eine Reihe von negativer Größe würde einen Fehler auslösen.

Es ist nicht definiertes Verhalten und eine gemeinsame Gotcha wenn das Pimpl Muster zu implementieren. Zum besten meines Wissens gibt es einfach nicht so etwas wie eine Warnung, dass der Compiler auszusenden erforderlich ist. Warnungen sind Wahl; Sie sind da, weil der Compiler Schriftsteller dachte sie nützlich wäre.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top