2015-08-19 13 views
7

Una volta che la mia classe non ha distruttore definito, codice seguente dà warning C4189: 'f' : local variable is initialized but not referencedmanualmente distruttore chiama non viene valutato come riferimento variabile

(f->~Fred() non è riconosciuto come riferimento f)

È questo un bug, o è questo comportamento standard?

struct Fred 
{ 
    int a, b; 
    //~Fred(){} 
}; 

int main() 
{ 
    char memory[sizeof(Fred)]; 

    void * place = memory; 

    Fred* f = new(place)Fred(); 

    f->~Fred(); 
} 

Questo codice è naturalmente privo di senso (è campione di lavoro minima), ma ottengo questo errore in scenario reale quando si scrive piscina allocatore e di utilizzarlo come

template <typename T> 
void CallDestructor(T * t) 
{ 
    t->~T(); 
} 

Io utilizzare Visual Studio 2013 avvertimento livello 4 ho testato su alcuni compilatori on-line senza preavviso, ma non sono sicuro di quello che è il loro livello di avviso

+1

Questo avviso viene attivato in entrambi i build di Debug e Release? Cosa succede se il distruttore effettivamente fa qualcosa? – Banex

+0

@Banex Se il distruttore fa qualcosa, va tutto bene. Una volta definito il distruttore (anche quello vuoto), tutto va bene. – relaxxx

+0

@relaxxx Bene, allora chiamare un distruttore vuoto è un non-operatore ed è come non chiamarlo del tutto, da qui l'avvertimento. Dovrebbe attivarsi anche quando si definisce uno vuoto ma è probabilmente una stranezza del compilatore. – Banex

risposta

7

questo è un bug, o si tratta di un comportamento normale?

Questo particolare avvertimento ("variabile locale viene inizializzata ma non fa riferimento") è qualcosa che non richiesto dalla norma. Per quanto riguarda la lingua, l'inizializzazione di una variabile locale e quindi la mancata referenziazione è perfettamente legale.

È un segno che il tuo codice potrebbe non fare ciò che intendevi fare, tuttavia, quindi il compilatore cerca di essere utile e ti avvisa di un costrutto discutibile. ("Hai dimenticato qualcosa qui?") Questo è completamente all'interno del dominio del compilatore, quindi non può essere un "comportamento standard" anche se hanno provato. ;-)

Sì, il compilatore dovrebbe realizzare che f->... costituisce un riferimento di f. Quindi l'avvertimento è un falso positiv. (Probabilmente perché l'intera faccenda è ottimizzata, essendo un no-op.) Tali cose accadono se si utilizzano livelli di avviso elevati.

Ma è un avviso , non un errore . Puoi tranquillamente ignorarlo o mascherarlo con #pragma warning (dato che stai lavorando con MSVC).