C'è un paio di cose strettamente malvagie sulle macro.
Sono in elaborazione di testo e non hanno ambito. Se si utilizza #define foo 1
, qualsiasi utilizzo successivo di foo
come identificatore avrà esito negativo. Ciò può portare a errori di compilazione e errori di runtime difficili da trovare.
Non accettano argomenti nel senso normale. È possibile scrivere una funzione che richiederà due valori int
e restituirà il valore massimo, poiché gli argomenti verranno valutati una volta e i valori utilizzati successivamente. Non è possibile scrivere una macro per farlo, poiché valuterà almeno un argomento due volte e fallirà con qualcosa come max(x++, --y)
.
Anche le insidie sono comuni. È difficile avere più affermazioni al loro interno e richiedono parecchie parentesi forse superflue.
Nel tuo caso, è necessario parentesi:
#define radian2degree(a) (a * 57.295779513082)
necessità di essere
#define radian2degree(a) ((a) * 57.295779513082)
e sei ancora calpestare chiunque scrive una funzione radian2degree
in qualche ambito interno, sicuro che quella la definizione funzionerà nel suo stesso ambito.
fonte
2009-10-28 22:07:45
In questo caso, degree2radian (45 + a/2.0) non fa ciò che pensavi. Parlate sempre di ogni argomento dell'espansione - beh, quasi sempre; le principali eccezioni sono quando fai cose come incollare o stringere i token. –
quello che dice Jonathan - una cosa peggiore di vedere una definizione di macro che è un rompicoglioni da leggere a causa di tutti i dannati paren, sta arrivando attraverso una definizione di macro che non ha tutti quei dannati paren. –
C'è anche la convenzione ALLCAPS per le macro, che almeno le inserisce nel proprio pseudo-namespace. –