#define, #ifdef #undef #endif
-
05-07-2019 - |
Question
J'ai le code suivant
#define PROC_ADD
void main(void)
{
while(1)
{
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
}
}
Cependant, le code sera exécuté. Mais il n'exécutera pas le code dans else
après que le PROC_ADD
ne soit plus défini.
Je pense que la raison pourrait en être que vous ne pouvez définir et indéfinir que lors de la compilation, et non au moment de l'exécution. Cependant, je ne suis pas vraiment sûr.
La solution
Ce que vous faites est l'équivalent en temps de construction de:
int x = 1;
int main()
{
if (x)
{
...
x = 0;
}
else
{
...
}
}
ifdef, etc. se produisent au moment de la construction, mais pour votre exemple, ce n'est pas un problème. Une fois que vous avez évalué le if (formulaire d’exécution ou de compilation), vous devez décider de la branche à prendre. Changer quelque chose après que la décision a été prise ne change pas cette décision.
Autres conseils
La condition ifdef
est évaluée lorsque le préprocesseur y accède. Lorsque vous undef
PROC_ADD
dans le code ifdef
, le préprocesseur a déjà décidé de la section de code à inclure et de celle à ignorer.
De plus, oui: ifdef
, undef
, etc. sont traités au moment du pré-traitement - le compilateur ne voit même jamais ces directives dites. Cela signifie bien entendu que le code d'exécution ne voit jamais ces directives non plus.
Modifier : le préprocesseur fonctionne en effectuant un seul passage dans le fichier texte. Le préprocesseur ne se soucie même pas que votre fichier texte contienne du code C! Il n'a aucune connaissance que vos ifdef
s et vos else
et ce qui ne se trouve pas dans une boucle while
.
#define
ne fonctionne que pendant le prétraitement. Donc
#define PROC_ADD
void main(void)
{
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
}
sera traité de la manière suivante: puisque PROC_ADDR
est défini, le préprocesseur exclut complètement la branche #else
puis exécute #undef
, le code de branche #else
ne survit jamais au prétraitement et n'atteint jamais le compilateur.
Dans à peu près tous les langages de programmation ou syntaxes, une fois que l'exécution est entrée dans une branche d'un conditionnel (dans ce cas, la condition est #ifdef
, même si la condition change pendant l'exécution de la branche, les autres branches ne seront jamais exécutées.
Je suis sûr que vous ne vous attendriez pas à ce que ceci soit imprimé "Bonjour", voulez-vous?
if (i == 1)
i = 0;
else
printf("Hello\n");
En gros, ce que vous dites, c'est que le code sous la branche else
doit toujours s'exécuter, puis simplement le retirer d'une branche et le mettre directement dans le code .
Le compilateur et l'exécution ne font qu'un seul passage entre les conditions, une fois la correspondance trouvée, ils ne cherchent plus.
Vous voulez donc que le code représenté par la deuxième section de commentaires soit exécuté toujours ? Pourquoi ne pas simplement faire
#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done
modifier
OK - si vous souhaitez modifier le comportement au moment de l’exécution, vous devez utiliser des constructions au moment de l’exécution (telle qu’une variable servant d’indicateur). Comme nous le disons tous;), les directives pré-processeur sont évaluées une seule fois, lors de la compilation.
Pensez-y de cette façon: la partie else
du code suivant n'est pas exécutée même si x
a été défini sur false
dans la zone < code> si section.
La condition est vérifiée dans la ligne si (x)
elle-même - une fois entré dans ce bloc, il ne recalcule pas chacune des sections else
suivantes - le compilateur a déjà pris une décision à ce sujet.
bool x = true;
if(x)
{
//do something
x = false;
}
else
{
//else code
}