Est-il sûr de supposer que NULL
se traduit toujours par faux en C?
void *somePtr = NULL;
if (!somePtr) {
/* Cela sera-t-il toujours exécuté? */
}
Ou devrait-on faire une vérification explicite de la valeur de NULL
?
Est-il sûr de supposer que NULL
se traduit toujours par faux en C?
void *somePtr = NULL;
if (!somePtr) {
/* Cela sera-t-il toujours exécuté? */
}
Ou devrait-on faire une vérification explicite de la valeur de NULL
?
Oui. NULL évalue à faux, car en C, toute valeur non nulle est considérée comme vraie et toute valeur nulle est considérée comme fausse. NULL est essentiellement l'adresse de zéro
et est traitée comme telle dans les comparaisons, et je crois qu'elle serait convertie en un entier pour la vérification booléenne. Je m'attends à ce que votre code soit lisible par toute personne familière avec le langage C, bien que je ferais probablement la vérification de manière explicite.
En programmation C et C++, deux pointeurs nuls sont garantis de 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 un pointeur vers void), donc un pointeur nul sera égal à NULL.
Réf : http://en.wikipedia.org/wiki/Null_pointer#Null_pointer
Une vérification explicite peut être plus claire dans certains cas, mais c'est un idiome C qui est garanti par le langage d'être valide. :)
La norme n'est pas très claire sur la question : il est garanti que 0 converti en un type de pointeur sera un pointeur nul, mais à ma connaissance cela ne spécifie pas ce qui se passera lorsqu'un pointeur nul est converti en int!
Le langage 'C' date d'une époque où (void*)0 pouvait réellement être un pointeur valide. Ce n'est pas si loin, les microprocesseurs 8080 et Z80 avaient un vecteur d'interruption à l'adresse 0. Face à de telles choix d'architecture, il ne pouvait rien faire d'autre que de laisser un fichier d'en-tête déclarer la valeur de NULL. Il y avait des compilateurs, aujourd'hui oubliés, où NULL n'était pas égal à (void*)0 (0xffff était la prochaine alternative), ce qui donnait à votre instruction if() un comportement indéfini.
Heureusement, C++ a mis fin à cela, un pointeur nul est affectable à 0 et testable contre 0.
Les unités de gestion de la mémoire (MMU) étaient probablement plus importantes que le C++ dans le changement.
Au sujet de votre phrase en C++ : c'est incorrect. 0 n'est pas un pointeur nul. 0 est une constante de pointeur nul. void *p = 0; maintenant, p est un pointeur nul. C'est une différence, car un pointeur nul a un type de pointeur, tandis qu'une constante de pointeur nul a un type entier et est une expression constante
C99 garantit que 0 converti en un type de pointeur sera également un pointeur nul - je ne me suis jamais soucié de lire les normes précédentes, donc je n'ai aucune idée de quand cela s'est produit...
Nous avions l'habitude d'aller plus loin en définissant une valeur nulle spécifique au type pour chacun de nos éléments typedef'ed : structs, int, longs, peu importe. De cette façon, la condition serait "if (foo != fooNil) { etc. }". Avertissement : J'avais l'habitude de travailler pour Simonyi chez Xerox, donc mon cerveau était contaminé.
@Peter Rowell : pendant longtemps, j'ai utilisé #define NIL(x) ((x)0) pour obtenir approximativement cet effet : NIL(foo), NIL(char *), NIL(bar), etc.
Oui (du moins pour tout compilateur C conforme aux normes!)
De la FAQ comp.lang.c:
Q: Est-il valide d'utiliser la comparaison abrégée des pointeurs ``if(p)'' pour tester les pointeurs non nuls? Et si la représentation interne des pointeurs nuls est non nulle?
R: C'est toujours valide.
NULL n'est qu'une définition de préprocesseur. Il se trouve dans stdio.h. En général, seule une personne folle le redéfinirait, mais c'est possible. Un exemple :
#include
#ifdef NULL
#undef NULL
#endif
#define NULL 1
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 d'étrange.
Mais si vous définissez NULL à 1 et assignez somePtr = NULL, vous obtiendrez au moins un avertissement que vous convertissez un entier en pointeur.
Ce serait tout simplement faux. Le compilateur et la bibliothèque standard C sont regroupés pour une raison. Si vous y touchez, vous cassez cela.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Je vous renvoie simplement à Question 5.3 du C-FAQ. Elle répond à cette question précise.
0 votes
Votre code n'utilise pas la valeur si NULL