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 contrôles 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 cette pratique expliquée nulle part sur le Web.
Cela vous permet de remplacer les macros lors de la compilation:
gcc -DMACRONAME=value
Les définitions du fichier d'en-tête sont utilisées par défaut.
Comme je l'ai dit dans le commentaire, imaginez cette situation:
foo.h
#define FOO 4
defs.h
#ifndef FOO
#define FOO 6
#endif
#ifndef BAR
#define BAR 4
#endif
bar.c
#include "foo.h"
#include "defs.h"
#include <stdio.h>
int main(void)
{
printf("%d%d", FOO, BAR);
return 0;
}
Imprime 44
.
Cependant, si le ifndef
conditionnel n'était pas là, le résultat serait des avertissements de compilation de la redéfinition MACRO et il affichera 64
.
$ gcc -o bar bar.c
In file included from bar.c:2:0:
defs.h:1:0: warning: "FOO" redefined [enabled by default]
#define FOO 6
^
In file included from bar.c:1:0:
foo.h:1:0: note: this is the location of the previous definition
#define FOO 4
^
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 le -D
drapeau pendant la compilation pour passer une valeur à une macro.
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.
Tout projet C réside sur plusieurs fichiers source. Lorsque vous travaillez sur un seul fichier source, les vérifications semblent (et en fait) ne servent à rien, 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 elle peut avoir déjà été définie dans un autre.
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 conseillé d'inclure son fichier config.h où il peut configurer ses valeurs. Si l'utilisateur a oublié certains définir le système peut continuer à fonctionner en raison du préréglage.
En utilisant
#ifndef BEEPTRIM_PITCH_RATE_DEGPS
#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f
#endif
permet à l'utilisateur de définir la valeur de la macro en utilisant l'argument de ligne de commande (dans gcc/clang/VS) -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
.
Il y a une autre raison importante. C'est une erreur de redéfinir une macro de préprocesseur différemment. Voir cette réponse à une autre SO question . Sans le #ifndef
vérifier, le compilateur devrait produire une erreur si -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f
est utilisé comme argument de ligne de commande dans l'appel du compilateur.