2009-10-13 8 views
7

Je suis confus pourquoi le code C++ suivant peut compiler. Pourquoi un appel pour supprimer la méthode de 0 ne produit aucune erreur ?!Supprimer NULL, mais aucune erreur de compilation

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

J'ai essayé de l'exécuter, et il ne m'a pas donné d'erreur du tout ...

+4

Le code ne compile pas - vous avez besoin d'un type pour le pointeur (comme vide) et non pas seulement une qualification; ce n'est pas (ancien) C. –

Répondre

19

Les garanties de langage C++ qui suppriment p fera rien si p est égal à NULL.

Pour plus d'informations, consultez la section 16.8,9 here:

+0

Encore, la question était pourquoi le code * compile *; pas pourquoi il n'y a pas une erreur d'exécution. – Josh

+5

Il est légal en C++ de supprimer un pointeur NULL, donc le compilateur est ok avec. –

+0

Est-il légal de déréférencer null aussi? Que diriez-vous de déborder la pile? Montrez-moi un compilateur qui commet des erreurs dans ces conditions ... – Josh

0

NULL et 0 ne sont pas la même chose. En C++ vous devez utiliser 0.

Il n'y a rien de syntaxiquement faux ou ambigu sur la suppression du pointeur nul. En fait, c'est par définition un non-op; c'est-à-dire que l'opération de suppression de la 0ème adresse équivaut à ne rien faire du tout.

+6

En fait, en C++, NULL est défini à 0. De plus, NULL vs 0 est un débat stylistique pour lequel il n'y a pas de réponse claire. – rlbond

+2

Il n'y a absolument aucune raison de préférer 0 à NULL en C++. Bien que, pour une raison quelconque, la recommandation d'utiliser "0 en C++" apparaisse ici et là de temps en temps. Je ne sais pas où cette légende urbaine provient, mais, encore une fois, il n'y a absolument rien de mal à utiliser NULL en C++ et en général, pour des raisons de lisibilité, NULL est preferrable sur 0. – AnT

+1

Stroustrup préfère 0 au lieu de NULL: http : //www.research.att.com/~bs/bs_faq2.html # null – ChrisW

0

Bien que votre exemple soit trivial, il n'existe aucun moyen pour un compilateur de connaître (au moment de la compilation) la valeur d'un pointeur.

Vous pouvez également déréférence NULL au moment de la compilation:

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

Compilateurs ne sont pas faites pour gérer ce genre de conditions d'erreur au moment de la compilation.

Et la plupart des (toutes?) Implémentations ont 'delete 0' en tant que non-opération. Ce code devrait fonctionner:

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

Bien que je ne suis pas sûr à 100% que :)

+3

Je ne pense pas que la suppression de null est une erreur d'exécution. – Jacob

+0

Vous avez raison. J'ai rencontré des problèmes de double suppression ... ou peut-être que j'imagine des choses? – Josh

+4

Tout compilateur C++ qui traite "delete NULL" comme autre chose qu'un no-op est un compilateur bogué. Le langage C++ spécifie que la suppression d'un pointeur NULL est sûre. (Appeler supprimer deux fois le même pointeur non-NULL, d'un autre côté, vous mettra dans le pétrin) –

1

Vous pouvez supprimer un pointeur NULL sans problème, et l'erreur que vous pouvez/pouvez ne sera pas au moment de la compilation, mais lors de l'exécution.

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

Habituellement, il est pratique de le faire:

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

Habituellement, il est mauvais de NULL un pointeur. La raison en est que les pointeurs doivent être encapsulés dans des classes. 'delete' se produit alors dans les destructeurs, après quoi le pointeur n'existe même plus ou en affectation, dans lequel le pointeur obtient une nouvelle valeur. Par conséquent, il n'existe généralement aucune méthode qui définirait le pointeur sur NULL. La seule exception évidente est une partie "optionnelle" d'un objet qui n'est plus nécessaire, mais considérez 'boost :: optionnel ' pour cela. – MSalters

1

Il est une norme de facto dans les langues C et C++ (et non seulement en eux) que les routines de désallocation des ressources doit accepter les arguments pointeur NULL et ne faites simplement rien. En fait, c'est une convention plutôt conventionnelle. Donc, la vraie question ici: pourquoi cela vous surprend-il? Qu'est-ce qui vous fait penser que cela devrait produire une erreur? De plus, qu'est-ce qui vous fait penser qu'il devrait échouer à compiler ??? BTW, votre question, la façon dont il est indiqué, ne semble pas avoir beaucoup de sens, puisque votre code ne peut pas vraiment compiler. La déclaration de pointeur supposée n'a pas de type, ce qui obligera tout compilateur à émettre un message de diagnostic.

+3

s/de-facto/de jure/- voir la citation de la norme ISO. – MSalters

Questions connexes