Utilisez-vous NULL ou 0 (zéro) pour les pointeurs en C ++?

195

Dans les premiers jours du C ++, quand il était boulonné sur C, vous ne pouviez pas utiliser NULL tel qu'il était défini comme (void*)0. Vous ne pouviez pas affecter NULL à un pointeur autre que void*, ce qui le rendait inutile. À l'époque, il était admis que vous utilisiez 0(zéro) pour les pointeurs nuls.

À ce jour, j'ai continué à utiliser zéro comme pointeur nul, mais ceux qui m'entourent insistent pour l'utiliser NULL. Personnellement, je ne vois aucun avantage à donner un nom ( NULL) à une valeur existante - et puisque j'aime aussi tester les pointeurs en tant que valeurs de vérité:

if (p && !q)
  do_something();

alors utiliser zéro a plus de sens (comme si vous utilisez NULL, vous ne pouvez pas logiquement utiliser p && !q- vous devez comparer explicitement NULL, sauf si vous supposez qu'il NULLest zéro, auquel cas pourquoi utiliser NULL).

Y a-t-il une raison objective de préférer zéro à NULL (ou vice versa), ou est-ce simplement une préférence personnelle?

Edit: Je devrais ajouter (et je voulais dire à l'origine) qu'avec RAII et les exceptions, j'utilise rarement des pointeurs zéro / NULL, mais parfois vous en avez encore besoin.

camh
la source
9
attendez, un pointeur nul n'est-il pas nécessaire pour être évalué comme faux, que null soit égal à zéro en interne ou non?
Mooing Duck

Réponses:

191

Voici le point de vue de Stroustrup à ce sujet: FAQ sur le style et la technique C ++

En C ++, la définition de NULLest 0, il n'y a donc qu'une différence esthétique. Je préfère éviter les macros, donc j'utilise 0. Un autre problème avec NULLest que les gens croient parfois à tort qu'il est différent de 0 et / ou pas un entier. Dans le code pré-standard, NULLétait / est parfois défini comme quelque chose d'inadapté et donc devait / doit être évité. C'est moins courant de nos jours.

Si vous devez nommer le pointeur nul, appelez-le nullptr; c'est ce qu'on appelle en C ++ 11. Ensuite, nullptrsera un mot-clé.

Cela dit, ne vous inquiétez pas pour les petites choses.

Martin Côté
la source
8
Bjarne a écrit ceci avant que C ++ 0x ne commence à travailler sur un nouveau type nul. Ce sera le cas que NULL sera utilisé pour ce type lorsqu'il sera disponible pour une plate-forme, et je pense que vous verrez un changement C dans le consensus général à ce sujet.
Richard Corden
124

Il y a quelques arguments (dont l'un est relativement récent) qui, je crois, contredisent la position de Bjarne à ce sujet.

  1. Documentation de l'intention

L'utilisation NULLpermet d'effectuer des recherches sur son utilisation et met également en évidence le fait que le développeur voulait utiliser un NULLpointeur, qu'il soit interprété par le compilateur comme NULLou non.

  1. La surcharge du pointeur et de 'int' est relativement rare

L'exemple que tout le monde cite est:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

Cependant, au moins à mon avis, le problème avec ce qui précède n'est pas que nous utilisons NULL pour la constante de pointeur nul, c'est que nous avons des surcharges de «foo» qui prennent des types d'arguments très différents. Le paramètre doit également être un int, car tout autre type entraînera un appel ambigu et générera ainsi un avertissement utile du compilateur.

  1. Les outils d'analyse peuvent aider AUJOURD'HUI!

Même en l'absence de C ++ 0x, il existe aujourd'hui des outils disponibles qui vérifient qu'il NULLest utilisé pour les pointeurs et qui 0est utilisé pour les types intégraux.

  1. C ++ 11 aura un nouveau std::nullptr_ttype.

C'est le dernier argument de la table. Le problème de 0et NULLest activement résolu pour C ++ 0x, et vous pouvez garantir que pour chaque implémentation qui fournit NULL, la toute première chose qu'ils feront est:

#define NULL  nullptr

Pour ceux qui utilisent NULLplutôt que 0, le changement sera une amélioration de type sécurité avec peu ou pas d' effort - si quoi que ce soit , il peut aussi attraper quelques bugs où ils ont utilisé NULLpour 0. Pour quiconque utilise 0aujourd'hui ... euh ... eh bien j'espère qu'ils ont une bonne connaissance des expressions régulières ...

Richard Corden
la source
1
Ce sont là de très bons points, je dois l'admettre. Je suis heureux que C ++ 0x ait un type nul, je pense que cela rendra beaucoup de choses plus propres.
Rob
2
@Richard, pourquoi ne pas faire le contraire? Vous pouvez utiliser Meyers nullptr_t, puis lorsque 0x devient disponible, vous supprimez le #includeet restez en sécurité jusqu'au bout.
fnieto - Fernando Nieto
15
#define NULL nullptrsemble dangereux. Pour le meilleur ou pour le pire, beaucoup de code hérité utilise NULL pour des choses autres que 0. Par exemple, les descripteurs sont souvent implémentés comme un type intégral et leur définition NULLn'est pas rare. J'ai même vu des abus comme utiliser NULLpour définir un charsur un terminateur zéro.
Adrian McCarthy
8
@AdrianMcCarthy: Je dirais seulement que c'était dangereux s'il y avait un danger que le code se compile silencieusement et ait une signification différente. Je suis presque sûr que ce n'est pas le cas, donc en fait toutes les utilisations incorrectes de NULL seraient détectées.
Richard Corden
3
@RichardCorden: Um, cela suppose que ces autres utilisations de NULLsont en fait incorrectes. De nombreuses API sont utilisées depuis longtemps NULLavec des descripteurs, et c'est en fait l'utilisation documentée avec beaucoup d'entre elles. Il n'est pas pragmatique de les briser soudainement et de déclarer qu'ils le font mal.
Adrian McCarthy
46

Utilisez NULL. NULL montre votre intention. Que ce soit 0 est un détail d'implémentation qui ne devrait pas avoir d'importance.

Andy Lester
la source
28
0 n'est pas un détail d'implémentation. La norme définit 0 comme étant n'importe quel modèle de bits représentant un pointeur nul.
Ferruccio
5
Comme si ..!! Mec, C ++ est un langage de bas niveau! Utilisez 0, c'est un idiome bien connu.
hasen
8
Je comprends que cela fait partie de la norme. C'est un détail d'implémentation en ce qui concerne la lecture du code. Le lecteur devrait penser "pointeur NULL" et non "0 qui dans ce cas signifie pointeur NULL, pas un nombre avec lequel je pourrais faire de l'arithmétique."
Andy Lester
3
+1. D'accord avec Andy. @Ferruccio, les détails d' implémentation de l'idée du programmeur ne sont pas les mêmes que ceux définis par l'
utilisateur
si vous utilisez NULL, dans un code simple sans en-tête complexe, vous trouverez l'erreur "NULL n'est pas défini dans cette portée" ..
ArtificiallyIntelligence
38

J'utilise toujours:

  • NULL pour les pointeurs
  • '\0' pour les caractères
  • 0.0 pour flotteurs et doubles

où 0 ferait bien. Il s'agit de signaler l'intention. Cela dit, je ne suis pas anal à ce sujet.

Andrew Stein
la source
25
vous devriez probablement utiliser 0.0F pour les flottants, pour éviter le
typage
35

J'ai arrêté d'utiliser NULL au profit de 0 il y a longtemps (ainsi que la plupart des autres macros). Je l'ai fait non seulement parce que je voulais éviter les macros autant que possible, mais aussi parce que NULL semble être devenu sur-utilisé dans le code C et C ++. Il semble être utilisé chaque fois qu'une valeur 0 est nécessaire, pas seulement pour les pointeurs.

Sur les nouveaux projets, je mets ceci dans un en-tête de projet:

static const int nullptr = 0;

Maintenant, lorsque les compilateurs compatibles C ++ 0x arrivent, tout ce que j'ai à faire est de supprimer cette ligne. Un avantage appréciable de ceci est que Visual Studio reconnaît déjà nullptr en tant que mot clé et le met en évidence de manière appropriée.

Ferruccio
la source
4
L'utilisation de NULL sera plus portable à long terme. 'nullptr' sera disponible pour certaines plates-formes et pas pour d'autres. Votre solution ici nécessite que vous utilisiez le préprocesseur autour de votre déclaration pour vous assurer qu'elle n'est présente que lorsque cela est nécessaire. NULL le fera automatiquement.
Richard Corden
6
Je ne suis pas d'accord. Il sera moins portable à court terme jusqu'à ce que les compilateurs rattrapent leur retard. À long terme, il sera tout aussi portable et peut-être un peu plus lisible.
Ferruccio
4
De plus, vous pouvez toujours #define nullptr NULL pour votre compilateur non-C ++ 0x.
Anteru
Je suis d'accord que NULLc'est surutilisé, je l'ai vu utilisé pour faire référence au caractère de terminaison zéro dans une chaîne! Je ne pense pas que cela justifie de l'éviter complètement.
Mark Ransom
21
    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

La morale de l'histoire. Vous devez utiliser NULL lorsque vous traitez avec des pointeurs.

1) Il déclare votre intention (ne me faites pas rechercher dans tout votre code en essayant de déterminer si une variable est un pointeur ou un type numérique).

2) Dans certains appels d'API qui attendent des arguments variables, ils utiliseront un pointeur NULL pour indiquer la fin de la liste d'arguments. Dans ce cas, l'utilisation d'un '0' au lieu de NULL peut poser des problèmes. Sur une plate-forme 64 bits, l'appel va_arg veut un pointeur 64 bits, mais vous ne passerez qu'un entier 32 bits. Il me semble que vous comptez sur les autres 32 bits pour être mis à zéro pour vous? J'ai vu certains compilateurs (par exemple l'icpc d'Intel) qui ne sont pas si gracieux - et cela a entraîné des erreurs d'exécution.

abonette
la source
NULLn'est peut-être pas portable et n'est pas sûr. Il peut y avoir des plates-formes qui restent #define NULL 0(selon la FAQ de Stroustrup: Dois-je utiliser NULL ou 0? Cité par la question principale et c'est parmi les premiers résultats de recherche). Au moins dans l'ancien C ++, 0a une signification conceptuelle particulière dans le contexte du pointeur. Vous ne devriez pas penser concrètement aux bits. Notez également que dans des contextes différents entiers ( short, int, long long) « sizeof(0)» sera différent. Je pense que cette réponse est un peu erronée.
FooF
(Personnellement en tant que programmeur C dans la vie quotidienne, je suis venu visiter cette question pour comprendre pourquoi les gens veulent utiliser à la NULLplace de (char *)0, (const char *)0ou (struct Boo *)0ou (void *)0ou quoi que ce soit pour exprimer plus clairement l'intention - sans être (à mon avis) trop encombrant.)
FooF
1
Votez. cela se passe au compilateur msvc2013 C. en 64 bits, 0 lors de la conversion en pointeur n'est pas garanti d'être NULL Pointer.
pengMiao
NULL est bien défini dans la norme, il est donc absolument portable. mais l'utilisation de NULL est plus claire, et après la mise à niveau vers C ++ 11, vous pouvez rechercher et remplacer NULL pour être nullptr facilement, mais pour 0, comment pouvez-vous faire pour cela?
chen3feng
17

Si je me souviens bien, NULL est défini différemment dans les en-têtes que j'ai utilisés. Pour C, il est défini comme (void *) 0, et pour C ++, il est défini comme juste 0. Le code ressemblait à quelque chose comme:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

Personnellement, j'utilise toujours la valeur NULL pour représenter des pointeurs nuls, cela rend explicite le fait que vous utilisez un pointeur plutôt qu'un type intégral. Oui en interne, la valeur NULL est toujours 0 mais elle n'est pas représentée comme telle.

De plus, je ne compte pas sur la conversion automatique des entiers en valeurs booléennes, mais je les compare explicitement.

Par exemple, préférez utiliser:

if (pointer_value != NULL || integer_value == 0)

plutôt que:

if (pointer_value || !integer_value)

Autant dire que tout cela est résolu dans C ++ 11 où l'on peut simplement utiliser à la nullptrplace de NULL, et nullptr_tc'est aussi le type de a nullptr.

Daemin
la source
17

Je dirais que l'histoire a parlé et que ceux qui ont plaidé en faveur de l'utilisation de 0 (zéro) se sont trompés (y compris Bjarne Stroustrup). Les arguments en faveur de 0 étaient principalement l'esthétique et la "préférence personnelle".

Après la création de C ++ 11, avec son nouveau type nullptr, certains compilateurs ont commencé à se plaindre (avec des paramètres par défaut) de passer 0 à des fonctions avec des arguments de pointeur, car 0 n'est pas un pointeur.

Si le code avait été écrit en utilisant NULL, une simple recherche et remplacement aurait pu être effectuée via la base de code pour le rendre nullptr à la place. Si vous êtes coincé avec du code écrit en utilisant le choix de 0 comme pointeur, il est beaucoup plus fastidieux de le mettre à jour.

Et si vous devez écrire un nouveau code maintenant selon la norme C ++ 03 (et que vous ne pouvez pas utiliser nullptr), vous devriez vraiment utiliser NULL. Cela vous facilitera grandement la mise à jour à l'avenir.

Gaute Lindkvist
la source
Bjarne Stroustrup préfère utiliser 0 simplement parce qu'il n'aime pas les macros mais ne veut pas non plus introduire de nouveau mot-clé. l'histoire prouve qu'il avait tort.
chen3feng le
11

J'utilise habituellement 0. Je n'aime pas les macros, et il n'y a aucune garantie qu'un en-tête tiers que vous utilisez ne redéfinit pas NULL pour être quelque chose d'étrange.

Vous pouvez utiliser un objet nullptr comme proposé par Scott Meyers et d'autres jusqu'à ce que C ++ obtienne un mot clé nullptr:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

Google "nullptr" pour plus d'informations.

Jon-hanson
la source
10
Toute bibliothèque tierce qui définit NULL sur autre chose que 0 (ou (void*)0si elle est compilée en code C) ne demande que des problèmes et ne doit pas être utilisée.
Adam Rosenfield
3
Avez-vous déjà vu une bibliothèque qui redéfinit NULL? Déjà? Si une telle bibliothèque existait déjà, vous auriez de plus gros problèmes que le NULL redéfini, comme le fait que vous utilisez une bibliothèque suffisamment stupide pour redéfinir NULL.
Andy Lester
1
Il y a plus de dix ans, je me souviens vaguement d'avoir à gérer des en-têtes tiers, peut-être Orbix ou ObjectStore, qui définissaient NULL. Je pense que j'ai une haine pathologique des macros après avoir perdu plusieurs jours et nuits à essayer de faire fonctionner divers en-têtes tiers avec windows.h.
jon-hanson
3
"n'aime pas les macros" est une critique étrange d'une #define de type objet. Peut-être voulez-vous dire que vous n'aimez pas le préprocesseur C?
Andrew Prock
1
Redéfinir les macros standard est un comportement indéfini iirc.
Ayxan Haqverdili le
11

J'ai déjà travaillé sur une machine où 0 était une adresse valide et NULL était défini comme une valeur octale spéciale. Sur cette machine (0! = NULL), donc un code tel que

char *p;

...

if (p) { ... }

ne fonctionnerait pas comme prévu. Tu as dû écrire

if (p != NULL) { ... }

Bien que je pense que la plupart des compilateurs définissent NULL comme 0 ces jours-ci, je me souviens encore de la leçon d'il y a des années: NULL n'est pas nécessairement 0.

mxg
la source
27
Vous n'utilisiez pas de compilateur compatible. Le standard dit que NULL est 0 et que le compilateur doit convertir 0 dans un contexte de pointeur en une valeur NULL vraie correcte pour l'arc.
Evan Teran
17
Oui, tu as raison. C'était au milieu des années 80 avant que l'ANSI ne produise une norme C. La conformité n'existait pas à l'époque et les rédacteurs de compilateurs étaient libres d'interpréter le langage comme ils l'entendaient. C'est pourquoi une norme était nécessaire.
mxg
@EvanTeran Ce n'est pas vrai pour C. (void *)0doit comparer égal à NULL, mais ce n'est pas nécessairement le cas 0. Certaines personnes ont fait valoir que NULLdevrait être 0xffffffff...ou 0xf7ffffff...depuis 0x00peut être une adresse valide, mais jusqu'à présent, la plupart des implémentations utilisent NULL= 0.
yyny le
@yyny vous vous trompez. Il existe une différence entre la "constante nulle" et la "valeur nulle". La constante nulle est PAR DEFINITION, 0selon la norme, c'est ce que vous écrivez dans votre code. Cependant, le compilateur peut choisir d'émettre une valeur différente pour la constante nulle dans le code machine résultant. En d'autres termes, lorsque vous écrivez p = 0;(où p est un pointeur), le compilateur verra le 0comme la constante nulle. Mais lors de l'émission de l'instruction pour stocker "null", stockera la valeur nulle spécifique à la machine qui peut ou non être littéralement l'adresse 0x0.
Evan Teran
10

Je pense que la norme garantit que NULL == 0, vous pouvez donc faire l'un ou l'autre. Je préfère NULL car il documente votre intention.

Mark Ransom
la source
Si vous avez des structures imbriquées, je pense que dire foo.bar_ptr = (Bar *) 0exprime l'intention beaucoup plus clairement que foo.bar_ptr = NULL. Cette habitude permet également au compilateur de détecter les erreurs de conception erronée pour vous. Pour moi, foo.bar_ptr = 0exprime l'intention ainsi que l'utilisation NULLsi je sais que foo.bar_ptrc'est un pointeur.
FooF
9

L'utilisation de 0 ou de NULL aura le même effet.

Cependant, cela ne signifie pas qu'ils sont tous deux de bonnes pratiques de programmation. Étant donné qu'il n'y a pas de différence de performances, choisir une option de bas niveau par rapport à une alternative agnostique / abstraite est une mauvaise pratique de programmation. Aidez les lecteurs de votre code à comprendre votre processus de réflexion .

NULL, 0, 0.0, '\ 0', 0x00 et autres se traduisent tous par la même chose, mais sont des entités logiques différentes dans votre programme. Ils doivent être utilisés comme tels. NULL est un pointeur, 0 est une quantité, 0x0 est une valeur dont les bits sont intéressants, etc. Vous n'affecteriez pas '\ 0' à un pointeur qu'il compile ou non.

Je sais que certaines communautés encouragent la démonstration d'une connaissance approfondie d'un environnement en rompant les contrats de l'environnement. Les programmeurs responsables, cependant, créent un code maintenable et gardent ces pratiques hors de leur code.

Chris
la source
5

Étrange, personne, y compris Stroustroup, n'a mentionné cela. En parlant beaucoup de standards et d'esthétique, personne n'a remarqué qu'il est dangereux de l'utiliser 0à NULLla place de, par exemple, dans une liste d'arguments variables sur l'architecture où sizeof(int) != sizeof(void*). Comme Stroustroup, je préfère 0pour des raisons esthétiques, mais il faut faire attention à ne pas l'utiliser là où son type pourrait être ambigu.

Michael Krelin - hacker
la source
Et dans ces endroits dangereux vous pouvez toujours utiliser à 0condition que vous spécifiez que 0vous voulez dire - par exemple (int *)0, (char *)0, (const char *)0ou (void *)0ou(unsigned long long) 0 ou autre. À mon avis, cela exprime l'intention beaucoup plus clairement que NULL.
FooF
1
Bien sûr, si vous ne savez pas ce que cela NULLsignifie.
Michael Krelin - hacker
Personnellement, je trouve un peu désagréable de lancer inutilement quelque chose (void *)quand je pourrais utiliser le type exact. J'ai volontairement donné l'exemple d'un entier 64 bits (généralement) dans la liste car il est analogue au cas du pointeur. De plus, si je me souviens que l'ancien C ++ défini NULLcomme 0étant exact (cela fait des années que j'ai programmé en C ++), nous n'observons aucune amélioration de l'exactitude du programme. La nouvelle norme C ++ fournit heureusement un nullptrmot-clé, nous pouvons donc nous débarrasser de cette NULLlaideur et de toute la controverse lors de l'écriture de C ++ plus récent.
FooF
Eh bien, c'est pourquoi le casting en (void*)a été abstrait NULL. EtNULL exprime en fait l'intention assez clairement la plupart du temps. Et je pense que votre souvenir est faux. Je ne suis pas sûr des normes, mais en pratique, je pense que cela a été le cas (void*)0. Et oui, nullptrc'est un joli joli, bien que cela revienne au même NULL: spécifier un pointeur nul sans spécifier de type.
Michael Krelin - hacker
1
@FooF, sur certaines plateformes - peut-être. Dans ma réalité, cela a fonctionné et je suppose donc que cela a été défini comme un indicateur. Quant à la robustesse, oui, ce que j'essayais de dire que l'utilisation nullptrporte le même message que NULL, c'était uniquement à propos de l'expression de l'intention que vous avez mentionnée au tout début. (Prétraitement NULLsur gccrendements modernes __null, quels qu'ils soient).
Michael Krelin - hacker
4

J'essaie d'éviter toute la question en utilisant des références C ++ lorsque cela est possible. Plutôt que

void foo(const Bar* pBar) { ... }

vous pourriez souvent être capable d'écrire

void foo(const Bar& bar) { ... }

Bien sûr, cela ne fonctionne pas toujours; mais les pointeurs nuls peuvent être surutilisés.

Et
la source
3

Je suis avec Stroustrup sur celui-ci :-) Puisque NULL ne fait pas partie du langage, je préfère utiliser 0.

Rob
la source
3

Préférence principalement personnelle, bien que l'on puisse faire valoir que NULL montre clairement que l'objet est un pointeur qui ne pointe actuellement vers rien, par exemple

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

IIRC, la norme n'exige pas que NULL soit égal à 0, donc utiliser ce qui est défini dans <stddef.h> est probablement le meilleur pour votre compilateur.

Une autre facette de l'argument est de savoir si vous devez utiliser des comparaisons logiques (conversion implicite en booléen) ou une vérification d'explicité par rapport à NULL, mais cela revient également à la lisibilité.

Jimmy
la source
3

Je préfère utiliser NULL car il indique clairement que votre intention est que la valeur représente un pointeur et non une valeur arithmétique. Le fait que ce soit une macro est malheureux, mais comme elle est si largement enracinée, il y a peu de danger (à moins que quelqu'un ne fasse quelque chose de vraiment stupide). J'aurais aimé que ce soit un mot-clé depuis le début, mais que pouvez-vous faire?

Cela dit, je n'ai aucun problème à utiliser les pointeurs comme valeurs de vérité en soi. Tout comme avec NULL, c'est un idiome enraciné.

C ++ 09 ajoutera la construction nullptr qui, je pense, est en retard depuis longtemps.

Michael Burr
la source
1

J'utilise toujours 0. Pas pour une vraie raison réfléchie, juste parce que quand j'ai appris le C ++ pour la première fois, j'ai lu quelque chose qui recommandait d'utiliser 0 et je l'ai toujours fait de cette façon. En théorie, il pourrait y avoir un problème de confusion dans la lisibilité, mais en pratique, je n'ai jamais rencontré une seule fois un tel problème en milliers d'heures-homme et en millions de lignes de code. Comme le dit Stroustrup, ce n'est vraiment qu'un problème esthétique personnel jusqu'à ce que la norme devienne nullptr.

Gérald
la source
1

Quelqu'un m'a dit une fois ... Je vais redéfinir NULL en 69. Depuis, je ne l'utilise plus: P

Cela rend votre code assez vulnérable.

Éditer:

Tout dans la norme n'est pas parfait. La macro NULL est une constante de pointeur NULL C ++ définie par l'implémentation qui n'est pas entièrement compatible avec la macro C NULL, ce qui, outre le type masquant implicite, la convertit en un outil inutile et sujet aux erreurs.

NULL ne se comporte pas comme un pointeur nul mais comme un littéral O / OL.

Dites-moi l'exemple suivant n'est pas déroutant:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

C'est à cause de tout cela, dans le nouveau standard apparaît std :: nullptr_t

Si vous ne voulez pas attendre le nouveau standard et que vous voulez utiliser un nullptr, utilisez au moins un bon comme celui proposé par Meyers (voir le commentaire jon.h).

fnieto - Fernando Nieto
la source
5
NULLest une partie bien définie de la norme C ++. Laisser les personnes qui aiment redéfinir les macros standard modifier le code dans votre projet rend votre code «vulnérable»; l'utilisation NULLne le fait pas.
CB Bailey
1

Eh bien, je préconise de ne pas utiliser du tout les pointeurs 0 ou NULL lorsque cela est possible.

Leur utilisation entraînera tôt ou tard des erreurs de segmentation dans votre code. D'après mon expérience, cela et les pointeurs en géréral sont l'une des plus grandes sources de bogues en C ++

aussi, cela conduit à des instructions "if-not-null" partout dans votre code. Beaucoup plus agréable si vous pouvez toujours compter sur un état valide.

Il existe presque toujours une meilleure alternative.

Janv P
la source
2
Une erreur de segmentation garantie (et elle est garantie sur les systèmes modernes lorsque vous déréférencer 0) est utile pour le débogage. Bien mieux que de déréférencer des déchets aléatoires et d'obtenir qui sait quel résultat.
Courses de légèreté en orbite
-4

Définir un pointeur sur 0 n'est tout simplement pas si clair. Surtout si vous venez dans un langage autre que C ++. Cela inclut C ainsi que Javascript.

J'ai récemment delt avec du code comme ceci:

virtual void DrawTo(BITMAP *buffer) =0;

pour une fonction virtuelle pure pour la première fois. J'ai pensé que c'était un jiberjash magique pendant une semaine. Quand j'ai réalisé qu'il s'agissait simplement de définir le pointeur de fonction sur a null(car les fonctions virtuelles ne sont que des pointeurs de fonction dans la plupart des cas pour C ++), je me suis lancé.

virtual void DrawTo(BITMAP *buffer) =null;

aurait été moins déroutant que cette basterdation sans un espacement approprié pour mes nouveaux yeux. En fait, je me demande pourquoi C ++ n'emploie pas les minuscules nullcomme il emploie les minuscules faux et vrai maintenant.

Pizzach
la source
En général, je préfère NULl à 0 pour les pointeurs. Cependant '= 0;' est la manière idiomatique de déclarer une fonction virtuelle pure en C ++. Je vous conseillerais fortement de ne pas utiliser '= NULL;' pour ce cas particulier.
danio
C'est le commentaire le plus drôle sur StackOverflow. Vous savez probablement déjà maintenant que l'exemple que vous avez donné est une syntaxe pour une fonction virtuelle pure et non un pointeur. Et oui @danio a raison, vous ne devriez pas utiliser NULL pour une fonction virtuelle pure.
sgowd