Pourquoi NULL n'est-il pas déclaré?

87

J'ai un problème avec ce constructeur de structure lorsque j'essaye de compiler ce code:

typedef struct Node
{
    Node( int data ) //
    {
        this->data = data;
        previous = NULL; // Compiler indicates here
        next = NULL;
    }

    int data;
    Node* previous;
    Node* next;
} NODE;

quand je viens, cette erreur se produit:

\linkedlist\linkedlist.h||In constructor `Node::Node(int)':|
\linkedlist\linkedlist.h|9|error: `NULL' was not declared in this scope|
    ||=== Build finished: 1 errors, 0 warnings ===|

Le dernier problème était la structure, mais cela fonctionnait bien quand c'était dans mon main.cpp, cette fois, c'est dans un fichier d'en-tête et me pose ce problème. J'utilise Code :: Blocks pour compiler ce code

se détendre
la source

Réponses:

139

NULLn'est pas une constante intégrée dans les langages C ou C ++. En fait, en C ++, c'est plus ou moins obsolète, utilisez simplement un littéral simple à la 0place, le compilateur fera la bonne chose en fonction du contexte.

Dans le C ++ plus récent (C ++ 11 et supérieur), utilisez nullptr(comme indiqué dans un commentaire, merci).

Sinon, ajoutez

#include <stddef.h>

pour obtenir la NULLdéfinition.

se détendre
la source
7
NULL fait partie de stddef.h, pas de stdlib.h. Techniquement, vous n'êtes pas assuré de l'obtenir dans le cadre de stdlib.h bien que j'admette que ce serait assez surprenant si vous ne le faisiez pas.
CB Bailey
8
NULL est défini dans les en-têtes C suivants: stddef.h, stdlib.h, stdio.h, locale.h, string.h et time.h (et wchar.h si vous comptez C99).
Michael Burr
8
<cstddef>est l'option la plus propre.
Fred Foo
29
N'utilisez PAS "0" lorsque vous voulez dire "NULL"! Il y a une différence : la sémantique. Ne sous-estimez jamais l'importance de savoir ce qu'est quelque chose et d'utiliser le bon mot, même si le compilateur vous permettra de vous en sortir!
imallett
13
@ 6502 Je ne parle pas de ça; 0 et NULL ont la même valeur (presque) toujours, donc utiliser '\ 0' ou 0 fonctionnera accidentellement. Le problème est la sémantique. L'utilisation de NULL est plus expressive, car elle indique que la valeur est une question est un pointeur, pas seulement un entier.
imallett
34

Utilisez NULL. Il est juste # défini comme 0 de toute façon et il est très utile de le distinguer sémantiquement de l'entier 0.

Il y a des problèmes avec l'utilisation de 0 (et donc NULL). Par exemple:

void f(int);
void f(void*);

f(0); // Ambiguous. Calls f(int).

La prochaine version de C ++ (C ++ 0x) comprend nullptrpour résoudre ce problème.

f(nullptr); // Calls f(void*).
Eric
la source
5
Il est défini comme ((void *)0)par la plupart des implémentations de bibliothèques standard C.
Triang3l
1
C'est la meilleure réponse courte (et techniquement précise) que j'ai jamais lue sur le sujet: NULL vs 0 vs nullptr. Merci!
jose.angel.jimenez
2
@SiPlus ((void *)0)est incorrect en C ++, car il void*n'est pas coercible à d'autres types de pointeurs comme dans C. glibc, par exemple, #define NULL 0quand __cplusplusest défini.
rpjohnst
16

NULLn'est pas une partie native du langage C ++ de base, mais elle fait partie de la bibliothèque standard. Vous devez inclure l'un des fichiers d'en-tête standard qui incluent sa définition. #include <cstddef>ou #include <stddef.h>devrait être suffisant.

La définition de NULLest garantie disponible si vous incluez cstddefou stddef.h. Ce n'est pas garanti, mais vous obtiendrez très probablement sa définition si vous incluez à la place de nombreux autres en-têtes standard.

CB Bailey
la source
12

Incluez-vous "stdlib.h" ou "cstdlib" dans ce fichier? NULL est défini dans stdlib.h / cstdlib

#include <stdlib.h>

ou

#include <cstdlib>  // This is preferrable for c++
Andy White
la source
2
NULL fait partie de stddef.h, pas de stdlib.h
awiebe
@awiebe C'est ce que je pensais jusqu'à il y a cinq minutes - selon C99, plusieurs fichiers d'en-tête différents doivent le définir. La section 7.17 requiert stddef.h pour, 7.20 l'exige dans stdlib.h, et il y en a probablement quelques autres.
AJM-Reinstate-Monica
4

Ne pas utiliser NULL, C ++ vous permet d'utiliser le sans ornement à la 0place:

previous = 0;
next = 0;

Et, comme en C ++ 11, vous ne devriez généralement pas utiliser l'un NULL ou l' autre ou0 puisqu'il vous fournit un nullptrtype std::nullptr_t, qui est mieux adapté à la tâche.

paxdiablo
la source
33
J'ai tendance à penser que NULL est une documentation utile indiquant que vous avez l'intention d'utiliser une constante de pointeur nul plutôt qu'une constante entière, bien que je ne m'oppose pas à l'utilisation de 0. J'admets que vous ne tirez aucun avantage pratique pour le moment , mais si / quand vous adoptez la prochaine version C ++, cela donne un bon début pour les endroits à changer pour utiliser la nouvelle constante nullptr.
CB Bailey
1
Je suis d'accord avec vous deux, bien sûr. Soit dit en passant, c'est à la fois bien qu'on documente, on utilise un pointeur, mais aussi bien que l'on documente en fait un entier. considérez printf ("% p \ n", NULL); // OH, UB. Ou si vous avez deux surcharges, void f (int); void f (void *); vous pourriez penser que f (NULL); appelle la version void * lors de la consultation rapide de l'appel. f (0); documentera le fait qu'il appellera réellement la version int, mais ne documentera pas le fait que vous avez l'intention de passer un pointeur :( Bien que nullptr le corrige :)
Johannes Schaub - litb