> #define (D)READ(A) ADDR = A; D = DATA;
Soll das D ein Argument von READ sein? Das geht so nicht. Argumente
stehen (wie auch bei Funktionen) immer nach dem Makronamen in
Klammern. Also so
1 | #define READ(D,A) ADDR = A; D = DATA;
|
oder so
1 | #define READ(A,D) ADDR = A; D = DATA;
|
Außerdem birgen die zwei Anweisungen in der Makrodefinition einen
Fallstrick. Verwendest du es in folgendem Kontext
1 | if(u>5)
|
2 | READ(data, 0x1234);
|
wird die zweite Anweisung des Makros immer ausgeführt, unabhängig
vom Ergebnis des if-Ausdrucks.
Etwas besser wird es, wenn die Anweisungen geklammert werden:
1 | #define READ(D,A) { ADDR = A; D = DATA; }
|
Damit ist obiges Problem beseitigt, aber
1 | if(u>5)
|
2 | READ(data, 0x1234);
|
3 | else
|
4 | ...
|
ergibt einen Syntaxfehler, weil zwischen dem '}' und dem 'else' ein
';' steht. Workaround: Das Semikolon weglassen, das sieht dann aber
nicht mehr C-like aus.
Dieses Problem wird behoben, wenn man das Makro folgendermaßen
definiert:
1 | #define READ(D,A) do { ADDR = A; D = DATA; } while(0)
|
Jetzt sieht zwar das Makro hässlich aus, dafür darf beim Aufruf des
Makros immer ein Semikolon dahinter stehen (auch vor einem 'else' wie
in obigem Beispiel). Das hässliche Makro schaut man, wenn es einmal
funktioniert, sowieso nicht mehr an.