Pointeur de nombre entier sans conversion

Lorsque j’appelle une fonction qui attend un pointeur et que je passe une valeur, je reçois cet avertissement et j’aime cela.

Mais lorsque la valeur est littéralement “0”, je ne reçois pas l’avertissement. Je pense que c’est parce que C pense que c’est null-pointeur, et non une valeur. Est-il possible d’obtenir des avertissements pour les littéraux 0, car j’ai déjà eu quelques bugs à cause de cela.

GCC prend en charge un atsortingbut non nonnull sur les parameters de fonction qui peut faire ce que vous voulez (tant que l’option d’avertissement -Wnonnull est activée):

 void* foo( int* cannot_be_null) __atsortingbute((nonnull (1))) ; int main(int argc, char *argv[]) { int x; foo(&x); foo(0); // line 13 - generates a -Wnonnull warning return 0; } 

Lorsque compilé avec gcc -c -Wnonnull test.c je reçois:

 test.c: In function 'main': test.c:13:5: warning: null argument where non-null required (argument 1) [-Wnonnull] 

Vous pouvez forcer ceci à être une erreur avec -Werror=nonnull .

Notez que cet avertissement est uniquement émis lorsque le littéral pointeur null (un autre nom pour 0 ) est utilisé – le code suivant ne déclenche pas l’avertissement:

 int* p = NULL; foo(p); 

Pas avec un compilateur C brut malheureusement. Vous devriez essayer un outil anti-peluche, comme attelle, qui pourrait vous aider à ce sujet (je ne suis pas sûr, cependant).

Je pense que la conversion en null est probablement assez insortingnsèque au compilateur – Il devrait cependant être facile de vérifier statiquement ces cas car ils sont assez uniques.

Si vous prévoyez de transmettre null et non (int) 0, utilisez une énumération ou une définition de NULL explicite, puis tout élément correspondant au modèle YourFunction (0); (en laissant de l’espace) est définitivement invalide. Grep pourrait être utilisé assez facilement pour cela si vous voulez utiliser une technologie de pointe. Comme le suggère Fabien, divers outils anti-peluche pourraient être en mesure de le faire.

J’essaie toujours de me rappeler lors du codage que si vous le pouvez, faites en sorte que les choses fausses soient aussi fausses que possible, de manière à pouvoir les détecter plus facilement.

Cette question est similaire à la question. Should I use symbolic names like TRUE and FALSE for Boolean constants, or plain 1 and 0?

Les programmeurs C doivent comprendre que NULL et 0 sont interchangeables dans des contextes de pointeur, et qu’un uncast 0 est parfaitement acceptable. Toute utilisation de NULL (par opposition à 0) doit être considérée comme un rappel gentil qu’un pointeur est impliqué; les programmeurs ne devraient pas en dépendre (ni pour leur propre compréhension, ni pour celle du compilateur) pour distinguer les 0 du pointeur des 0 entiers.

Ce n’est que dans les contextes de pointeur que NULL et 0 sont équivalents. NULL ne doit pas être utilisé lorsqu’un autre type de 0 est requirejs, même si cela peut fonctionner, car cela envoie un message stylistique erroné. (En outre, ANSI autorise la définition de NULL comme étant ((void *) 0), ce qui ne fonctionnera pas du tout dans des contextes sans pointeur.) En particulier, n’utilisez pas NULL lorsque le caractère nul ASCII (NUL) est souhaité. Fournissez votre propre définition

 #define NUL '\0' 

si tu dois.

Cette information est de ce lien

Est-il possible d’obtenir des avertissements pour les littéraux 0?

Je ne sais pas pour un, de toute façon vous ne voulez pas ça. La valeur numérique constante 0, lorsqu’elle est affectée à un pointeur, est implicitement traitée comme NULL sans la convertir en un type de pointeur.