59 votes

Existe-t-il une bonne raison de toujours mettre une définition entre parenthèses en C?

Clairement, il y a des moments où define s doit avoir des parenthèses, comme ceci:

 #define WIDTH 80+20

int a = WIDTH * 2; //expect a==200 but a==120
 

J'ai donc toujours indiqué entre parenthèses, même s'il ne s'agit que d'un seul chiffre:

 #define WIDTH (100)
 

Quelqu'un de nouveau dans la catégorie C m'a demandé pourquoi je fais cela. J'ai donc essayé de trouver un cas extrême où l'absence de parenthèses sur un seul chiffre define pose des problèmes, mais je ne peux pas en penser à un.

Un tel cas existe-t-il?

48voto

Alexander Gessler Points 26717

Oui. Le préprocesseur opérateur de concaténation (##) va entraîner des problèmes, par exemple:

#define _add_penguin(a) penguin ## a
#define add_penguin(a) _add_penguin(a)

#define WIDTH (100)
#define HEIGHT 200    

add_penguin(HEIGHT) // expands to penguin200
add_penguin(WIDTH)  // error, cannot concatenate penguin and (100) 

De même pour stringization (#). C'est clairement un cas de coin et n'a probablement pas d'importance, considérant à quel WIDTH va sans doute être utilisé. Pourtant, c'est quelque chose à garder à l'esprit sur le préprocesseur.

(La raison pour laquelle l'ajout de la deuxième pingouin échoue est un subtil détail de la prétraitement des règles en C99 - iirc il échoue parce que la concaténation de deux non-espace réservé prétraitement des jetons doit toujours résulter d'un simple prétraitement jeton - mais cela est sans importance, même si la concaténation a été autorisé, il serait encore donner un résultat différent de celui du unbracketed #define!).

Toutes les autres réponses sont correctes seulement dans la mesure où il n'a pas d'importance du point de vue du C++ scanner car, en effet, un certain nombre est atomique. Cependant, à ma lecture de la question, il n'y a aucun signe que seuls les cas avec aucune autre préprocesseur d'expansion doit être considérée, de sorte que les autres réponses, même si je suis totalement d'accord avec les conseils qui y sont contenues, de mal.

30voto

asveikau Points 16871

Parfois, vous devez écrire du code non avec l'actualité des mises en garde à l'esprit, mais avec les mises en garde de la prochaine fois, il va être édité.

Dès maintenant votre macro est un simple entier. Imaginez quelqu'un de modification dans l'avenir. Disons qu'ils ne sont pas vous, mais quelqu'un qui est moins prudent, ou au plus pressé. La parenthèse est là pour les rappeler à mettre toutes les modifications dans la parenthèse.

Ce genre de pensée est une bonne habitude à C. personnellement, je écrire du code dans un style qui, certaines personnes pourraient trouver "redondant", avec des choses comme ça, mais en particulier en ce qui concerne la gestion des erreurs. La redondance est pour la maintenabilité et la composabilité des futures éditions.

9voto

Nicoretti Points 1156

Comme Blagovest Buyukliev dit:

La définition se compose d'un jeton unique (un seul opérande, pas seulement les opérateurs), les parenthèses ne sont pas nécessaires, car un seul jeton (100) est un atome indivisible lorsque lexing et de l'analyse.

Mais je vous recommande les règles suivantes quand il s'agit de macros:

  1. Éviter de fonction comme les macros @voir Lundin commentaire.

Si vous souhaitez utiliser la fonction comme les macros mal considérer les 2 règles:

  1. Toujours utiliser des crochets pour les arguments dans les macros
  2. Utiliser uniquement une macro argument une fois

Pourquoi la règle 1.? (Pour garder l'ordre des opérations correct)

#define quad(x) (x*x)
int a = quad(2+3);

sera étendue à d':

int a = (2+3*2+3);

Pourquoi la règle 2.? (Afin d'assurer un effet secondaire n'est appliqué qu'une fois)

#define quad(x) (x*x)
int i = 1;
int a = quad(i++);

sera étendue à d':

int a = i++ * i++;

8voto

Blagovest Buyukliev Points 22767

Chaque fois que la définition consiste en un seul jeton (un seul opérande, pas d'opérateurs), les parenthèses ne sont pas nécessaires, car un seul jeton (tel que 100 ) est un atome indivisible lors de l'exploration et de l'analyse.

7voto

NPE Points 169956

Puisque 100 est un simple jeton, je doute que vous trouviez un coin où les parenthèses importent (pour un seul jeton!)

C'est toujours une bonne habitude IMO, puisqu'ils peuvent avoir de l'importance quand plusieurs jetons sont impliqués.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X