web-dev-qa-db-fra.com

NULL est-il toujours faux?

Est-il sûr de supposer que NULL se traduit toujours par false en C?

void *somePtr = NULL;

if (!somePtr) {
  /* This will always be executed? */
}

Ou une vérification explicite de la valeur de NULL doit-elle être effectuée?

49
Sydius

Oui. NULL est évalué à faux, car C considère toute valeur non nulle comme vraie et toute valeur nulle comme fausse. NULL est essentiellement l'adresse zero et est traité comme tel dans les comparaisons, et je pense qu'il serait promu en entier pour la vérification booléenne. Je m'attendrais à ce que votre code soit lisible par toute personne familière avec C bien que je rendrais probablement la vérification explicite.

En programmation C et C++, deux pointeurs nuls sont garantis pour comparer égaux; ANSI C garantit que tout pointeur nul sera égal à 0 dans une comparaison avec un type entier; en outre, la macro NULL est définie comme une constante de pointeur nul, c'est-à-dire la valeur 0 (soit en tant que type entier, soit convertie en pointeur pour annuler), donc un pointeur nul se comparera égal à NULL.

Réf: http://en.wikipedia.org/wiki/Null_pointer#Null_pointer

51
tvanfosson

Il n'est jamais sûr de supposer quoi que ce soit.

Une vérification explicite est également plus claire sur ce que vous testez.

18
akatakritos

Le langage 'C' date d'une époque où (void *) 0 pouvait en fait être un pointeur valide. Il n'y a pas si longtemps, les microprocesseurs 8080 et Z80 avaient un vecteur d'interruption à l'adresse 0. Face à de tels choix d'architecture, il ne pouvait rien faire mais laisser un fichier d'en-tête déclarer la valeur de NULL. Il y avait des compilateurs, oubliés depuis longtemps, où NULL n'était pas égal à (void *) 0 (0xffff était l'alternative suivante), donnant ainsi à votre instruction if () un comportement indéfini.

Heureusement, C++ met fin à cela, un pointeur nul est assignable à partir de 0 et testable par rapport à 0.

17
Hans Passant

Oui (au moins pour tout compilateur C conforme aux normes!)

De la comp.lang.c FAQ :

Q: La comparaison abrégée des pointeurs `` if (p) '' pour tester les pointeurs non nuls est-elle valide? Que faire si la représentation interne des pointeurs nuls est différente de zéro?

R: C'est toujours valable.

11
Captain Segfault

NULL n'est qu'une définition de préprocesseur. C'est dans stdio.h. En règle générale, seule une personne folle le redéfinirait, mais c'est possible. Un exemple:

#include <stdio.h>
#ifdef NULL
#undef NULL
#define NULL 1
#endif

void main()
{

        if (NULL)
                printf("NULL is true\n");
        else
                printf("NULL is false\n");
}

Ce code affichera "NULL est vrai". Essayez-le si vous ne me croyez pas. Votre compilateur pourrait même ne pas vous avertir que vous faites quelque chose de bizarre.

5
bdowling

Je vous renvoie simplement à Question 5. de la C-FAQ. Il répond à cette question exacte.

2
anon

NULL est défini comme un pointeur constant qui est garanti pour pointer vers un endroit inutile/inexistant en mémoire. La plupart des implémentations de NULL sont ((void *)0) mais il n'est pas obligatoire qu'il en soit ainsi.

2
dreamlax

Oui, surtout.

Tout d'abord, NULL est un typedef. Je pourrais vous visser royalement en disant dans un en-tête précédemment inclus

#define NULL 1

Cela n'a peut-être pas beaucoup de sens, mais depuis quand le code des autres a-t-il déjà eu un sens? :)

En outre, bien qu'il soit probablement syntaxiquement sûr, il n'est pas sémantiquement correct. NULL signifie "rien", ni vrai ni faux ou une valeur booléenne ou int ou chaîne. Cela signifie "un symbole pour rien". Donc, tester NULL ressemble plus à un problème philisophique: si un arbre tombe dans la forêt et if(listener), est-ce que ça fait du bruit?

Faites une faveur à tout le monde et soyez clair sur les tests contre NULL.

0
Matt