Il y a quelques trucs strictement diaboliques à propos des macros.
Ils sont un traitement de texte et ne sont pas définis. Si vous #define foo 1
, toute utilisation ultérieure de foo
en tant qu'identificateur échouera. Cela peut conduire à des erreurs de compilation bizarres et à des bugs d'exécution difficiles à trouver.
Ils ne prennent pas d'arguments dans le sens normal. Vous pouvez écrire une fonction qui prendra deux valeurs int
et renvoyer le maximum, car les arguments seront évalués une fois et les valeurs utilisées par la suite. Vous ne pouvez pas écrire de macro pour faire cela, car il va évaluer au moins un argument deux fois, et échouer avec quelque chose comme max(x++, --y)
.
Il y a aussi des pièges courants. Il est difficile d'obtenir plusieurs énoncés en eux, et ils nécessitent beaucoup de parenthèses éventuellement superflues.
Dans votre cas, vous avez besoin entre parenthèses:
#define radian2degree(a) (a * 57.295779513082)
a besoin d'être
#define radian2degree(a) ((a) * 57.295779513082)
et vous intensifions encore personne qui écrit une fonction radian2degree
dans une certaine marge intérieure, confiant que ce définition fonctionnera dans sa propre portée.
Dans ce cas, degree2radian (45 + a/2.0) ne fait pas ce que vous pensiez. Toujours entre parenthèses chaque argument dans l'expansion - bien, presque toujours; Les principales exceptions sont lorsque vous faites des choses comme le collage de jetons ou le chaînage. –
ce que Jonathan dit - une chose pire que de voir une définition de macro qui est une douleur dans le cul à lire à cause de toutes les foutues parens, est de tomber sur une définition macro qui n'a pas toutes ces foutues parens. –
Il existe également la convention ALLCAPS pour les macros, qui les place au moins dans leur propre pseudo-espace de noms. –