C: Utilisation efficace des macros
Question
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
Si j'utilisais le style ci-dessus comme modèle pour déclarer des macros, quelles réserves auriez-vous?
La solution
-
mettez des parenthèses autour de l'argument (cela évite les problèmes de passage d'expressions)
-
ne pas mettre; à la fin (l'utilisation sera plus naturelle)
#define NULLCHECK (x) assert ((x)! = (void *) 0)
Autres conseils
De manière générale, vous devez toujours mettre les macro-arguments entre parenthèses dans l’extension, c’est-à-dire dans votre cas
assert((x) != (void*) 0)
En effet, si vous ne spécifiez pas d'expressions (plutôt que de simples variables), vous risquez de gâcher le développement des variables.
Je vous suggérerais également de NE PAS mettre le point-virgule à la fin de la définition de la macro, de sorte que vous deviez l'appeler comme suit
NULLCHECK(pSomething);
qui a juste l'air plus C-like & amp; cohérent avec le reste de votre code.
Un changement que je pourrais apporter serait de commenter le #endif
:
#endif // MACROS_NULLCHECK_H_
Cela facilite la compréhension de ce que #endif
fait là lorsque le fichier dépasse la taille d'un écran.
Quelques bonnes pratiques de macro de CERT C Wiki de codage sécurisé :
PRE00-C. Préférez les fonctions en ligne ou statiques aux macros fonctionnelles.
PRE01-C. Utilisez des parenthèses dans les macros autour des noms de paramètres
PRE02-C. Les listes de remplacement de macro doivent être entre parenthèses
PRE03-C. Préférez les typedefs à définir pour les types d'encodage
PRE10-C. Enroulez des macros à plusieurs instructions dans une boucle do-while
PRE11-C. Ne terminez pas une définition de macro d'instruction unique avec un point-virgule
PRE31-C. N'appelez jamais une macro non sécurisée avec des arguments contenant une affectation, une incrémentation, une décrémentation, un accès volatile ou un appel de fonction
PRE32-C. N'utilisez pas de directives de préprocesseur dans les arguments de macro
Ça a l'air bien. C’est un motif que j’utilise beaucoup.
Pour appliquer le ;
, utilisez
#define NULLCHECK(x) do { assert((X)); } while (0)