Est-ce que #if MACRO est équivalent à #ifdef MACRO?

J’ai le code que je veux avoir deux modes, debug et verbose . Je les définis dans mon fichier d’en-tête comme,

#define verbose TRUE #define debug TRUE 

Jusqu’à présent, dans mon code, je viens d’utiliser

 #if(debug) //code #endif 

mais est-il plus approprié d’utiliser

 #ifdef debug // code #endif 

J’ai lu quelque chose sur les macros du préprocesseur mais cela n’avait pas de sens à l’époque. Donc, j’ai une question, est-ce que #if defined MACRO équivalent à #ifdef MACRO ? et quel est le meilleur pour activer / désactiver une section de code particulière?

 #ifdef MACRO #if defined (MACRO) 

fera exactement la même chose. Toutefois, la définition (MACRO) est simplement une expression évaluée à 0 ou 1 à l’intérieur du #if et peut être combinée à d’autres expressions. Par exemple

 #if defined (MACRO) && ! defined (MACRO2) // Do this #else // Do that #endif 

Essayez de faire cela avec #ifdef – vous ne pouvez pas, sauf si votre code devient vraiment maladroit.

#if defined(MACRO) est identique à #ifdef MACRO , mais est plus long. D’autre part, cela permet d’append des conditions supplémentaires avec || ou && .

#if MACRO est similaire à #ifdef MACRO mais pas à 100%. Si MACRO est 0 alors #if MACRO sera négatif – il faut que MACRO soit défini et non 0 . #ifdef vérifie seulement s’il est défini même sans valeur ( #define MACRO ).

Il est maintenant moderne d’utiliser #if et d’activer / désactiver les définitions avec la valeur 1 ou 0:

#define FLAG_X 1 // or 0

Non, ils ne sont pas du tout équivalents. Une twig #if MACRO est compilée si MACRO évaluée à une valeur autre que zéro. D’autre part, une twig #ifdef MACRO est compilée si MACRO est défini , quel que soit le résultat. Alors

 #include  #define VAR_SET_TO_TRUE 1 #define VAR_SET_TO_FALSE 0 int main() { #if VAR_SET_TO_TRUE printf("#if VAR_SET_TO_TRUE\n"); #endif #if VAR_SET_TO_FALSE printf("#if VAR_SET_TO_FALSE\n"); #endif #if VAR_UNSET printf("#if VAR_UNSET\n"); #endif #ifdef VAR_SET_TO_TRUE printf("#ifdef VAR_SET_TO_TRUE\n"); #endif #ifdef VAR_SET_TO_FALSE printf("#ifdef VAR_SET_TO_FALSE\n"); #endif #ifdef VAR_UNSET printf("#ifdef VAR_UNSET\n"); #endif } 

va sortir

 #if VAR_SET_TO_TRUE #ifdef VAR_SET_TO_TRUE #ifdef VAR_SET_TO_FALSE 

Notez que la ligne printf("#ifdef VAR_SET_TO_FALSE\n"); est compilé pendant que la ligne printf("#if VAR_SET_TO_FALSE\n"); n’est pas. Le premier est compilé, car VAR_SET_TO_FALSE est défini , même si sa valeur est false .

Si je lis correctement votre question, le titre est trompeur, il devrait être

 Is #if MACRO equivalent to #ifdef MACRO? 

Ils ne sont pas équivalents mais ils peuvent (et sont souvent) tous les deux utilisés pour spécifier des modes binarys activés ou désactivés. Le choix est, à mon avis, une question de préférence personnelle.

Vous utilisez la première option et avez soit

 #define verbose true 

ou

 #define verbose false 

puis vérifiez le mode en utilisant soit

 #if verbose 

ou

 #if !verbose 

En fait, je vous recommanderais d’utiliser TRUE ou 1 au lieu de true et FALSE ou 0 au lieu de false, car true et false sont (ou peuvent être) des valeurs C / C ++ et le pré-processeur n’a pas access à C / Valeurs C ++.

Quoi qu’il en soit, l’autre façon courante de spécifier les modes binarys consiste à définir le drapeau ou à le laisser non défini, auquel cas vous pouvez avoir

 #define verbose any thing (including nothing) goes here 

ou laisser de côté le #define.

et ensuite vous pouvez tester si le drapeau est défini, soit avec

 #ifdef verbose 

ou son équivalent

 #if defined(verbose) 

REMARQUE: dans ce cas, vous ne testez pas la valeur de l’indicateur, vous devez uniquement vérifier s’il est défini.

Si cela est plus pratique, vous pouvez également vérifier si le drapeau est indéfini avec

 #ifndef verbose 

ou son équivalent

 #if !defined(verbose) 

Si nous avons assez de cervelle, nous pouvons faire une différence. Mais il est obscur et implique un comportement indéfini, donc cela n’a aucune conséquence si nous nous soucions uniquement de savoir si le code est ssortingctement conforme à ISO C.

Le formulaire #if defined ... est susceptible de se comporter différemment si une macro #define defined ... été traitée. Dans la norme ISO C99, il était écrit en ce qui concerne les directives #if et #elif :

Avant l’évaluation, les invocations de macros de la liste des jetons de prétraitement qui deviendront l’expression de la constante de contrôle sont remplacées (à l’exception des noms de macros modifiés par l’opérateur unaire défini), comme dans le texte normal.

Il n’est pas nécessaire que l’opérateur unaire defined soit reconnu et protégé contre le traitement en tant que macro; c’est juste l’un des “jetons de prétraitement qui deviendront l’expression …”. L’opérateur defined n’est reconnu à ce stade que dans le but de protéger son argument contre le développement.

Si la définition de define tant que macro est simplement autorisée, les occurrences de definition sont ensuite remplacées (y compris dans les arguments de #if directives de pré- #if ), ce qui interfère avec #if defined , sans affecter #ifdef .

Peut-être que cette partie de la langue a été resserrée depuis le C99.