Yep.
Wie du schon bemerkt hast, ist es immer eine gute Idee
ein Makro zu Klammern wenn es eine Formel darstellen soll.
Aber es gibt noch mehr Fallen mit Makros.
#define DOUBLE(x) (2 * x)
und jetzt lass mal berechnen
i = 5;
j = DOUBLE(i+1)
Das Ergebnis ist nicht 12, sondern 11.
Die Makroexpansion zeigt auch warum. Aus DOUBLE(i+1)
wird
j = ( 2 * i+1 );
und Aufgrund der Matheregeln wird das als (2*i)+1
gerechnet.
Lösung:
#define DOUBLE(x) ( 2 * (x) )
Das ist aber nicht alles. Es gibt noch mehr. Gefährlich wird
es auch immer dann, wenn ein Makroargument in der Expansion
2 mal vorkommt
#define MAX(x,y) ( (x) < (y) ? (y) : (x) )
und das wendest du mal auf
i = 5;
j = 6;
k = MAX(i++,j++)
an. Welches sind die Werte von i und j nach der Maximumbestimmung?
i hat dann den Wert 6, aber j hat den Wert 8!
Aus diesen Gründen ist man bei Formeln meist mit einer Funktion
auf der besseren Seite
int max( int x, int y )
{
return x < y ? y : x;
}
Da gibt es keine derartigen überraschenden Effekte. Und da der Compiler
solche Funktionen in den meisten Fällen inlinen wird, hat man auch
keinen Laufzeit-Penalty.