Je suis confus pourquoi le code C ++ suivant peut compiler. Pourquoi un appel à supprimer la méthode de 0 ne produisait aucune erreur ?! J'ai essayé de l'exécuter, et cela ne m'a pas donné d'erreur du tout ... P > p>
5 Réponses :
null et 0 ne sont pas la même chose. En C ++, vous devriez utiliser 0. P>
Il n'y a rien de syntaxiquement mal ou ambigu de la suppression du pointeur NULL. En fait, c'est par définition un non-op; C'est-à-dire que l'opération de supprimer la 0ème adresse est équivalente à ne rien faire du tout. P>
En fait, en C ++, NULL est défini pour être 0. De plus, NULL vs. 0 est un débat stylistique pour lequel il n'existe aucune réponse claire.
Il n'y a absolument aucune raison de préférer 0 sur NULL en C ++. Bien que, pour une raison quelconque, la recommandation de "utiliser 0 en C ++" apparaît ici et là de temps à autre. Je ne sais pas où provient de cette légende urbaine, mais, encore une fois, il n'y a absolument rien de mal à utiliser NULL en C ++ et généralement, pour des raisons de lisibilité, NULL est préférable à 0.
STROSTRUP préfère 0 au lieu de NULL: recherche.att.com/~bs/bs_faq2 .html # null
Il me semble que NULL est meilleur style, si seulement parce que lorsque vous recherchez des problèmes de pointeur, vous pouvez le rechercher. Dans un programme qui utilise 0 au lieu de NULL, la recherche de 0 vous obtiendra à la fois des utilisations du pointeur et des entiers de 0, et les résultats supplémentaires non pertinents prendront plus de temps à parcourir.
La réponse n'est ni: nullptr code>. Comme il n'y a pas de
nullptr code> pourtant, vous pouvez créer ce type et régler le problème. Cela dit, je trouve
null code> moche. C'est tout-caps (laid), OBLY (Ugly) et Ick.
La préférence de STROSTRUP est basée sur son aversion des macros en général. En outre, il provient de ces âges sombres lorsque les fichiers d'en-tête C et C ++ étaient souvent mélangés et la définition C-seule NULL SA '(VOID *) 0' (totalement inappropriée pour C ++) fuit dans le code C ++. Ces temps sont longs et, une fois encore, il n'y a rien de mal avec NULL en code C ++.
Sauf que ça a l'air volumineux et moche :)
J'ai toujours ressenti la seule chose qui devrait être toutes les capuchons est des macros, comme do_something_with_it (x) code>. Les constantes ne sont pas des macros, elles sont:
statique const int gisisanumber = 123; code>. Vous ne tapez pas toutes les casquettes avec des noms de variables, n'est-ce pas? Je trouve l'affaire de chameau supérieure est une belle entre elles. De même, tout dans la langue C ++ est minuscule et il est beaucoup plus facile de lire si tout est uniforme,
nullptr code> sera totalement inférieur, alors pourquoi utiliser un remplacement qui est tout-haut? Lorsque NULL et 0 sont effondrés et nullptr est en place, s'habituer à toutes les capuchons est le chagrin d'amour qui attend de se produire.
null est (nul *) 0 dans certaines architectures. Il y a nullptr si vous êtes standard-garçon;]
Bien que votre exemple soit trivial, il n'y a aucun moyen pour un compilateur de savoir (au moment de la compilation) de la valeur d'un pointeur.
Vous pouvez également désarfirement nul à la compilation: p>
Object* pObject = new Object(); delete pObject; pObject = 0; delete pObject;
Vous avez raison. J'ai rencontré des problèmes de double suppression cependant ... ou peut-être que j'imaginais des choses?
Tout compilateur C ++ qui traite "Supprimer NULL" comme autre chose qu'un no-op est un compilateur de buggy. La langue C ++ spécifie que la suppression d'un pointeur NULL est sans danger. (Calling Supprimer deux fois sur le même pointeur non nul, d'autre part, vous aura des problèmes)
@Jeremy Friesner: Je reçois votre point de vue, mais du point de vue de Pedantic, "Supprimer null" est mal formé. "NULL" en C ++ est tenu de représenter un zéro intégré et «Supprimer» ne peut pas être appliqué à intégrale 0. «Supprimer NULL» est aussi mal formé que «Supprimer 0 ', c'est-à-dire :)
... 'Supprimer (int *) NULL' D'autre part est légal et est en effet nécessaire d'être un non-op.
La langue C ++ garantit que supprimer p ne fera rien si p est égal à Null. P>
Pour plus d'informations, consultez la section 16.8,9 ici < / a>: p>
Néanmoins, la question était de savoir pourquoi le code compile i>; Pas pourquoi n'y a-t-il pas une erreur d'exécution.
Il est légal en C ++ pour supprimer un pointeur NULL. Par conséquent, le compilateur est correct avec celui-ci.
Il est légal de déréférence null aussi? Que diriez-vous de déborder la pile? Montrez-moi un compilateur qui soit des erreurs sur ces conditions ...
En ce qui concerne le compilateur, toutes ces choses sont légales. Le temps d'exécution peut avoir une opinion différente, bien sûr ...
Wow, Josh, peut-être que je ne me trompe pas, mais vous semblez assez défensive ou quelque chose du genre. Supprimer NULL est bon, cela ne fait rien.
@JOSH: Le compilateur n'est pas censé détecter toutes les erreurs. C'est impossible. Le compilateur n'est requis que pour détecter les "violations de contraintes", qui sont explicitement décrites dans la spécification de la langue. Détecter toutes les autres erreurs est votre problème, pas le compilateur. Le pointeur nul de la derréférance est illégal, mais ce n'est pas une violation de la consisse, ce qui signifie que le compilateur n'est pas obligé de s'inquiéter à ce sujet. Il n'y a pas de simple moyen compilateur peut le détecter en général.
Gman - Point juste. Andreyt - C'est exactement mon point! J'ai lu la question différemment à vous les gars. Je le lis comme suit: "Pourquoi le compilateur ne prend pas ce genre de chose?". Vous les gars le lisez comme "pourquoi ne pas supprimer" null "illégal?". J'essayais d'expliquer la différence entre une exception de temps d'exécution et une erreur de compilateur, mais a échoué?
@JOSH On dirait que nous lisons la question d'une façon (la façon dont il a été écrit) et que vous le lisez une autre façon (la façon dont il n'a pas été écrit). La question demande clairement pourquoi supprimer NULL ne provoque pas d'erreur de compilation. La réponse est parce qu'elle est légale, bien définie, parfaitement bien.
@JOSH: Pour clarifier: Le compilateur ne ramasse pas "ce genre de chose", car cette chose (Supprimer NULL) est parfaitement légale et en fait, quelque chose que des programmeurs peuvent faire intentionnellement. Il serait puttement gênant si le compilateur détermine arbitrairement des caractéristiques autorisées par la langue. Par exemple, si votre fonction s'acquitte d'un objet obj code>, il peut être plus propre à
Supprimer obj; code> inconditionnellement que de vérifier. (Considérez quelque chose comme
si (obj == null || obj.num_to_do () == 0) {Supprimer obj; retour;} ... code> sur
si (obj == null) { retour;} if (obj.num_to_do () == 0) {Supprimer obj; retour;} ... code>)
Supprimer CODE> ING Un pointeur NULL est légal et a un comportement bien défini. La déséroférance d'un pointeur nul est légal et a un comportement indéfini.
Vous pouvez supprimer un pointeur NULL sans problème et l'erreur que vous pouvez / peut ne pas être au moment de la compilation mais à l'exécution. Habituellement, il est pratique de faire: P> ...
delete ptr;
ptr = NULL;
C'est généralement une mauvaise pratique de nuler un pointeur. La raison en est que les pointeurs doivent être encapsulés dans des classes. Supprimer CODE> puis survient aux 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'y a généralement aucune méthode qui définirait le pointeur sur NULL. La seule exception évidente est une partie "facultative" d'un objet qui n'est plus nécessaire, mais considérons
boost :: facultatif
Il s'agit d'une norme de facto dans les langues C et C ++ (et non seulement dans elles) que les routines de transaction de ressources doivent accepter des arguments de null-pointeur et ne rien faire simplement. En fait, c'est une convention plutôt convenable. Alors, la vraie question ici: pourquoi vous surprend-il? Qu'est-ce qui vous fait penser qu'il devrait produire une erreur? De plus, ce qui vous fait penser qu'il devrait échouer compiler em> ??? p>
BTW, votre question, la façon dont il est indiqué, ne semble pas avoir beaucoup de sens, car votre code ne peut réellement compiler. La déclaration de pointeur supposée manque de type, qui rendra tout compilateur à émettre un message de diagnostic. P>
S / DE FACTO / DE JURE / - Voir la citation de la norme ISO.
Le code ne compile pas - vous avez besoin d'un type pour le pointeur (tel que void) et pas seulement un qualificatif; Ce n'est pas (vieux) C.