2009-10-13 16 views
7

Sono confuso perché il seguente codice C++ può essere compilato. Perché una chiamata per eliminare il metodo di 0 non produce alcun errore ?!Elimina NULL ma nessun errore di compilazione

int *arr = NULL;  // or if I use 0, it's the same thing  
delete arr; 

ho provato a farlo funzionare, e non mi ha dato alcun errore a tutti ...

+4

Il codice non viene compilato: è necessario un tipo per il puntatore (come void) e non solo un qualificatore; questo non è (vecchio) C. –

risposta

19

Il garanzie lingua che cancellano p farà nulla se p è uguale a NULL C++.

Per maggiori informazioni, visitate la sezione 16.8,9 here:

+0

Ancora, la domanda era: perché il codice * compilava *; non perché non c'è un errore in fase di esecuzione. – Josh

+5

È legale in C++ cancellare un puntatore NULL, quindi il compilatore è ok con esso. –

+0

E 'legale anche il dereferenziazione null? Che ne dici di traboccare lo stack? Mostrami un compilatore che commetta errori in quelle condizioni ... – Josh

0

NULL e 0 non sono la stessa cosa. In C++ si dovrebbe usare 0.

Non c'è nulla di sintatticamente sbagliato o ambiguo sull'eliminazione del puntatore nullo. In realtà, questo è per definizione un no-op; in altre parole, l'operazione di eliminare lo 0 ° indirizzo equivale a non fare nulla.

+6

In realtà, in C++, NULL è definito come 0. Inoltre, NULL vs. 0 è un dibattito stilistico per il quale non esiste una risposta chiara. – rlbond

+2

Non c'è assolutamente alcun motivo per preferire 0 su NULL in C++. Sebbene, per qualche motivo, la raccomandazione di "usare 0 in C++" si presenti saltuariamente qua e là di tanto in tanto. Non so da dove provenga questa leggenda metropolitana, ma, ancora una volta, non c'è assolutamente nulla di sbagliato nell'usare NULL in C++ e generalmente, per motivi di leggibilità, NULL è preferibile su 0. – AnT

+1

Stroustrup preferisce 0 invece di NULL: http : //www.research.att.com/~bs/bs_faq2.html # null – ChrisW

0

Sebbene l'esempio sia banale, non è possibile per un compilatore sapere (in fase di compilazione) il valore di un puntatore.

È possibile anche dereferenziare nullo in fase di compilazione:

// this code compiles 
Object* pObject = 0; 
pObject->SomeMethod(); 

compilatori non sono costruiti per gestire questi tipi di condizioni di errore in fase di compilazione.

E la maggior parte (tutte?) Le implementazioni hanno 'cancella 0' come una non-operazione. Questo codice deve funzionare bene:

Object* pObject = new Object(); 
delete pObject; 
pObject = 0; 
delete pObject; 

Anche se non sono sicuro al 100% su questo :)

+3

Non penso che l'eliminazione di null sia un errore di run-time. – Jacob

+0

Hai ragione. Mi sono imbattuto in problemi di doppia eliminazione anche se ... o forse sto immaginando cose? – Josh

+4

Qualsiasi compilatore C++ che consideri "delete NULL" come qualcosa di diverso da un no-op è un compilatore buggato. Il linguaggio C++ specifica che l'eliminazione di un puntatore NULL è sicura. (Chiamare cancella due volte sullo stesso puntatore non NULL, d'altra parte, ti metterà nei guai) –

1

È possibile eliminare un puntatore NULL senza problemi, e l'errore si può/possono avere non sarà al momento della compilazione, ma in fase di esecuzione.

int *ptr_A = &a; 
ptr_A = NULL; 
delete ptr_A; 

solito è conveniente fare:

... 
delete ptr; 
ptr = NULL; 
+1

In genere è una pratica scorretta un puntatore NULL. La ragione è che i puntatori dovrebbero essere incapsulati nelle classi. 'delete' quindi si verifica in distruttori, dopo di che il puntatore non esiste nemmeno più o in assegnazione, in cui il puntatore ottiene un nuovo valore. Quindi, di solito non ci sono metodi che possano impostare il puntatore su NULL. L'unica ovvia eccezione è una parte "facoltativa" di un oggetto che non è più necessario, ma considera 'boost :: opzionale ' per quello. – MSalters

1

Si tratta di uno standard de-facto in linguaggi C e C++ (e non solo in essi) che le routine di risorsa deallocazione deve accettare argomenti null-pointer e semplicemente non fare nulla In realtà, è una convenzione piuttosto convenzionale. Quindi, la vera domanda qui: perché ti sorprende? Cosa ti fa pensare che dovrebbe produrre un errore? Inoltre, cosa ti fa pensare che non dovrebbe riuscire a compilare ???

BTW, la tua domanda, nel modo in cui viene dichiarata, non sembra avere molto senso, dal momento che il tuo codice in realtà non può essere compilato. La presunta dichiarazione del puntatore manca di un tipo, che farà sì che qualsiasi compilatore emetta un messaggio diagnostico.

+3

s/de facto/de jure/- vedere citazione dallo standard ISO. – MSalters

Problemi correlati