web-dev-qa-db-fra.com

Pourquoi ne pas appeler nullptr NULL?

Dans C++ 11, le mot clé nullptr a été ajouté en tant que constante de pointeur null de type plus sûr, car la précédente définition commune de NULL as 0 a quelques problèmes.

Pourquoi le comité des normes a-t-il choisi de ne pas appeler la nouvelle constante de pointeur nul NULL, ou de déclarer que NULL devrait être #defined à nullptr?

66
immibis

Stephan T. Lavavej (membre du comité standard C++) a expliqué qu'une fois dans un talk (55:35):

Alors qu'une implémentation est autorisée à #define NULL nullptr, cela casserait pas mal d'utilisations comme

int i = NULL;

et apparemment il y en a beaucoup. Ils ne pouvaient donc pas forcer le changement.

70
Baum mit Augen

nullptr est de type pointeur , tandis que NULL a tendance à être entier, et parfois dans les fonctions surchargées, vous besoin d'être clair que vous utilisez un pointeur et non un entier - c'est quand nullptr est utile.

Donc, pour vraiment répondre à votre question, NULL et nullptr ont deux fonctions différentes et la redéfinition l'une de l'autre cassera probablement beaucoup de choses dans les bases de code déjà existantes.

À côté de cela, vérifiez cela depuis site Web de Bjarne Stroustrup :

Dois-je utiliser NULL ou 0?

En C++, la définition de NULL est 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 NULL est que les gens croient parfois à tort qu'il est différent de 0 et/ou non d'un entier. Dans le code pré-standard, NULL était/est parfois défini sur quelque chose d'inadapté et devait/doit donc ê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, "nullptr" sera un mot-clé.

41
Kiloreux

Sans vraiment participer à la discussion au sein du comité des normes, il est difficile de dire avec certitude, mais je pense que cela casserait un code qui utilise NULL dans un sens où nullptr n'est pas suffisamment compatible. Et briser l'ancien code n'est jamais une bonne idée.

8
Mats Petersson

NULL n'est pas de type sécurisé. Pour des raisons historiques, il a été défini comme 0 sans transtypage, et le compilateur avertit par silence du nombre de transtypage pour pointer sur ce zéro spécial.

Pour l'instant, vous pouvez faire:

void* p = 0;

mais pas sans casting implicite:

void* p = 1234;

l'effet secondaire est qu'il peut être abusé en tant que valeurs numériques, comme une autre réponse mentionnée.

nullptr améliorez cela en appliquant qu'il s'agit d'un pointeur, vous ne pouvez pas l'affecter à un entier. Étant donné que le comportement est modifié, un nouveau nom est créé pour la compatibilité descendante.

Notez également que nullptr est géré par le compilateur, sa valeur réelle n'est pas exposée à l'utilisateur (comme zéro dans le cas de NULL). Il est beaucoup plus facile d'avoir une valeur dépendante de l'architecture, par exemple 0xdeadbeef, sans affecter la logique du code du programmeur.

8

Je vais démontrer un cas où la décision de définir nullptr comme un type différent aide à prévenir les bogues.

Considérez ces fonctions:

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

int main()
{
    foo(NULL); // oops
}

En C++ 98, le code ci-dessus appelle la fonction foo (int), car NULL est remplacé par 0, ce qui n'est probablement pas ce que vous vouliez.

Mais si vous appelez foo (nullptr) il appelle la bonne - foo (char *).

2
Minas Mina

Pourquoi le comité des normes a-t-il choisi de ne pas appeler la nouvelle constante de pointeur nul NULL

Vraisemblablement parce que le nouveau pointeur nul est un mot clé et que les mots clés ne peuvent pas être #defined, donc l'appeler NULL aurait rendu l'inclusion de tout en-tête C probablement mal formée.

ou déclarez que NULL doit être #defined à nullptr?

Le comité des normes permet que NULL soit #defined à nullptr, mais cela ne l'exige pas.

C++ 11 18.2 Types [support.types]/2: La macro NULL est une constante de pointeur nul C++ définie par l'implémentation dans la présente Norme internationale.

C++ 11 4.10 Conversions de pointeur [conv.ptr]/1: A constante de pointeur nul est une expression constante intégrale ( 5.19) prvalue de type entier qui vaut zéro ou une valeur de type std::nullptr_t.

La compatibilité descendante n'est pas un problème ici, toute utilisation de NULL qui suppose qu'il s'agit d'une forme de l'entier 0 n'est pas conforme à la norme. Les implémentations peuvent choisir de ne pas le faire pour tolérer ce type de comportement malveillant.

2
K-ballo

nullptr est introduit pour la sécurité des types et pour la clarté (probablement pour arrêter l'initialisation des types sans pointeur à l'aide de NULL).

Le NULL (type int) n'est pas changé en nullptr (type pointeur) pour éviter toute confusion et assurer la compatibilité descendante.

Ainsi, le train de pensée standard du comité est probablement lié à une transition en douceur de l'ancienne à la nouvelle notation sans provoquer d'ambiguïtés ni freiner un code déjà existant.

1
Ziezi