È ancora sicuro eliminare nullptr in c ++ 0x?


85

In c++03esso è abbastanza chiaro che l'eliminazione di un puntatore nullo non ha alcun effetto. Infatti, è esplicitamente affermato in §5.3.5/2quanto:

In entrambe le alternative, se il valore dell'operando di cancellazione è il puntatore nullo, l'operazione non ha effetto.

Tuttavia, nell'attuale bozza di c++0xquesta frase sembra mancare. Nel resto della bozza ho potuto trovare solo frasi che affermano cosa succede se l'operando dell'espressione di cancellazione non è la costante del puntatore nullo. L'eliminazione del puntatore nullo è ancora definita in c++0xe, in caso affermativo, dove?

Appunti:

Esistono prove circostanziali significative che suggeriscono che sia ancora ben definito.

Innanzitutto, ci sono le due frasi per §5.3.5/2affermarlo

Nella prima alternativa (oggetto di cancellazione), il valore dell'operando di cancellazione può essere un valore di puntatore nullo, ...

e

Nella seconda alternativa (cancella array), il valore dell'operando di cancellazione può essere un valore di puntatore nullo o ...

Questi dicono che l'operando può essere nullo, ma da soli non definiscono effettivamente cosa succede se lo è.

In secondo luogo, cambiare il significato di delete 0è un importante cambiamento radicale, e il comitato per gli standard sarebbe molto improbabile che effettui questo particolare cambiamento. Inoltre non si fa menzione che si tratti di una modifica sostanziale nell'Allegato sulla compatibilità (Allegato C) della c++0xbozza. L'allegato C è tuttavia una sezione informativa, quindi questo non ha alcuna influenza sull'interpretazione della norma.

D'altra parte, il fatto che l'eliminazione del puntatore nullo non abbia alcun effetto implica un ulteriore controllo in fase di esecuzione. In molto codice l'operando non può mai essere nullo, quindi questo controllo di runtime è in conflitto con il principio di zero overhead. Forse il comitato ha appena deciso di modificare il comportamento per portare lo standard c ++ più in linea con gli obiettivi di progettazione dichiarati del linguaggio.

Risposte:


102

5.3.5 / 7 dice:

Se il valore dell'operando di delete-expression non è un valore di puntatore nullo, delete-expression chiamerà una funzione di deallocazione (3.7.4.2). Altrimenti, non è specificato se verrà chiamata la funzione di deallocazione.

E 3.7.4.2/3 dice:

Il valore del primo argomento fornito a una funzione di deallocazione può essere un valore di puntatore nullo; in tal caso, e se la funzione di deallocazione è quella fornita nella libreria standard, la chiamata non ha effetto.

Quindi il comportamento è ben definito, a condizione che venga utilizzata la funzione di deallocazione standard o una funzione di deallocazione fornita dall'utente gestisce correttamente i puntatori null.


9
Poiché C ++ 14 "Se l'espressione restituisce un valore di puntatore nullo, non vengono chiamati distruttori e la funzione di deallocazione non viene chiamata."
Wormer

2
@ Wormer Non credo che quella pagina sia corretta. Lo standard C ++ 14 dice ancora "non è specificato se la funzione di deallocazione verrà chiamata" quando il puntatore è nullo (5.3.5 / 7).
Interjay

1
Per inciso, non è sicuro chiamare fclose () per un puntatore a file nullo. Su Ubuntu (e forse altri sistemi operativi), fclose (NULL) causa un errore di segmentazione.
Gerry Beauregard

7

D'altra parte, il fatto che l'eliminazione del puntatore nullo non abbia alcun effetto implica un ulteriore controllo in fase di esecuzione.

La nuova formulazione non rimuove quel controllo in fase di esecuzione per un puntatore nullo. Il contrario: la bozza di standard si avvicina ancora di più a dire che un'implementazione deve eseguire un test con puntatore nullo per essere conforme.

Inoltre degno di nota: il vecchio standard si contraddiceva in quanto diceva (5.3.5 / 2) che "se il valore dell'operando di cancellazione è il puntatore nullo l'operazione non ha effetto" ma successivamente ha detto che (5.3.5 / 7) l '"espressione-cancellazione chiamerà una funzione di deallocazione". La chiamata a una funzione è un effetto. Ciò è particolarmente vero poiché la funzione che viene chiamata potrebbe essere sostituita operator delete.

La nuova formulazione rimuove questa contraddizione, lasciando esplicitamente all'implementazione se la funzione di deallocazione viene chiamata in caso di eliminazione di un puntatore nullo.

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.