#si défini (x) || (y); est-ce valide?

Lors d’une revue, je suis tombé sur un morceau de code comme suit:

#if defined(x) || y 

Que signifie la déclaration ci-dessus? La condition s’exécutera-t-elle correctement?

Oui c’est valide.

Voici ce que dit la norme (C99) en 6.10p1:

 if-group: # if constant-expression new-line groupopt # ifdef identifier new-line groupopt # ifndef identifier new-line groupopt 

l’opérateur defined est vu comme opérateur unaire faisant partie d’une expression constante (6.10.1p1).

Dans votre exemple, la condition est évaluée comme vraie si la macro x est définie OU si y est défini et différent de 0

Le raisonnement pour cela est double.

Au lieu d’utiliser un #ifdef , vous utilisez l’opérateur defined pour pouvoir y utiliser des opérateurs logiques ( && , || , etc.), de sorte que vous n’ayez pas à dupliquer votre code pour qu’il soit correctement inclus s’il y a lieu. est plusieurs critères pour ce que vous devez définir.

De plus, à mon avis , je trouve qu’il est beaucoup plus facile de lire #if defined(x) que #ifdef x , et vous pouvez faire ce qui suit #if defined(x) && defined(y) , alors que ce n’est pas possible avec #ifdef .

Oui, puisque defined(x) est un booléen et renvoie true ou false.

La déclaration ci-dessus signifie “ou x est défini ou y est vrai”.

c’est correct mais c’est une mauvaise pratique. Pourquoi utiliser deux évaluations différentes (‘y’ et ‘définies (x)’) dans une seule condition? Cela pourrait être déroutant pour les autres. L’exemple ci-dessous montre une utilisation plus courante de || et && opérateurs contre les macros #defined:

 #define AA 1 #define BB 2 #if (defined AA) || (defined BB) #warning "A or B" #endif #if (defined AA) && (defined BB) #warning "A and B" #endif 

Lorsque le code ci-dessus était exécuté, l’utilisateur recevait ces messages à l’écran:

 #warning "A or B" #warning "A and B" 

Mais si le code était comme ça (AA n’était pas défini):

 #undefine AA #define BB 2 #if (defined AA) || (defined BB) #warning "A or B" #endif #if (defined AA) && (defined BB) #warning "A and B" #endif 

alors l’utilisateur recevra ce message:

 #warning "A or B"