Partout dans notre base de code C, je vois chaque macro définie de la manière suivante:
#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#endif
#ifndef BEEPTRIM_ROLL_RATE_DEGPS
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#endif
#ifndef FORCETRIMRELEASE_HOLD_TIME_MS
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#endif
#ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
#endif
Quelle est la justification de ces vérifications de définition au lieu de simplement définir les macros?
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#define BEEPTRIM_ROLL_RATE_DEGPS 0.2f
#define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f
#define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f
Je ne trouve pas cette pratique expliquée nulle part sur le Web.
c
macros
c-preprocessor
ifndef
Trevor Hickey
la source
la source
Réponses:
Cela vous permet de remplacer les macros lorsque vous compilez:
Les définitions du fichier d'en-tête sont utilisées par défaut.
la source
Comme je l'ai dit dans le commentaire, imaginez cette situation:
foo.h
defs.h
bar.c
Imprimera
44
.Cependant, si le conditionnel
ifndef
n'était pas là, le résultat serait des avertissements de compilation de redéfinition de MACRO et il sera imprimé64
.la source
ifdef
pour éviter de redéfinir).#infdef
s sont utilisées comme valeurs de «repli» ou «par défaut». Fondamentalement, "si l'utilisateur l'a configuré, très bien. Sinon, utilisons une valeur par défaut."#defines
dans un en-tête de bibliothèque qui font partie de l'ABI de la bibliothèque, vous ne devriez pas les encapsuler#ifndef
. (Ou mieux, utilisez unenum
). Je voulais juste préciser que ce#ifndef
n'est approprié que lorsque vous avez une définition personnalisée pour quelque chose dans une unité de compilation, mais pas une autre. Sia.c
inclut les en-têtes dans un ordre différent de celuib.c
, ils peuvent obtenir des définitions différentes demax(a,b)
, et l'une de ces définitions peut rompre avecmax(i++, x)
, mais l'autre peut utiliser des temporaires dans une expression-instruction GNU. Toujours déroutant au moins!#ifdef FOO
#error FOO already defined!
#endif
#define FOO x
Je ne connais pas le contexte, mais cela peut être utilisé pour donner à l'utilisateur la possibilité de remplacer les valeurs définies par ces définitions de macro. Si l'utilisateur définit explicitement une valeur différente pour l'une de ces macros, elle sera utilisée à la place des valeurs utilisées ici.
Par exemple, dans g ++, vous pouvez utiliser l'
-D
indicateur lors de la compilation pour passer une valeur à une macro.la source
Ceci est fait pour que l'utilisateur du fichier d'en-tête puisse remplacer les définitions de son code ou de l'indicateur -D du compilateur.
la source
Tout projet C réside sur plusieurs fichiers source. Lorsque vous travaillez sur un seul fichier source, les vérifications semblent (et en fait) inutiles, mais lorsque vous travaillez sur un grand projet C, il est recommandé de vérifier les définitions existantes avant de définir une constante. L'idée est simple: vous avez besoin de la constante dans ce fichier source spécifique, mais il se peut qu'elle ait déjà été définie dans un autre.
la source
Vous pourriez penser à un framework / bibliothèque qui donne à l'utilisateur un préréglage par défaut qui permet à l'utilisateur de le compiler et de travailler dessus. Ces définitions sont réparties dans différents fichiers et l'utilisateur final est invité à inclure son fichier config.h où il peut configurer ses valeurs. Si l'utilisateur en a oublié certains, le système peut continuer à fonctionner grâce au préréglage.
la source
En utilisant
permet à l'utilisateur de définir la valeur de la macro à l'aide de l'argument de ligne de commande (dans gcc / clang / VS)
-DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
.Il y a une autre raison importante. Redéfinir différemment une macro de préprocesseur est une erreur. Voir cette réponse à une autre question SO . Sans la
#ifndef
vérification, le compilateur doit produire une erreur s'il-DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
est utilisé comme argument de ligne de commande dans l'appel du compilateur.la source