#defines verschachteln

OP (Firma: FHK) #2702930
Lesenswert?

Hallo!

mein At2560 besitzt 4 UARTs. Ich moechte an einer Stelle festlegen, an 
welchem welches Gerät angeschlossen ist und dass das Makro dann von 
selbst die richtige uartX_puts - Prozedur (uart0_puts, uart1_puts, 
uart2_puts, uart3_puts verwendet.

Meine Traumvorstellung zum Senden ans Terminal ueber UART0:

#define uart_terminal 0   //terminal an UART0 angeschlossen
#define send_to_terminal  uart(uart_terminal)puts //gewaehltes uart 
eingebaut
send_to_terminal("hallo!"); //zusammengesetzt sendets zum terminal

Das funktioniert "natürlich" nicht, nur wie verschachtelt man #defines 
vernuenftig?
OP (Firma: FHK) #2702995
Lesenswert?

Meine Begeisterung hat sich gelegt:

Was tu ich falsch?
Die Beschreibung beschreibt die Verkettung von Makroparametern- ist das 
das gleiche als würde man (wie ich) Zeichenketten für den Compiler 
zusammenfügen wollen?

Nichtlaufendes Beispiel:
#define glue(a, b, c) a ## b ## c
glue(uart, 3, puts) ("hallo");
#2703051
Lesenswert?

perlbastel schrieb:
> Warte mal bis Karl Heinz (Buchegger) vorbeikommt, der wird es wissen...

:-)

Die Sache ist die.
Das hier
1
#define glue(a, b, c) a ## b ## c
2
glue(uart, 3, puts) ("hallo");

macht genau das, was er will.
Nur: Das hat er nicht so in seinem richtigen Code stehen. Dort steht 
eher so was wie
1
#define UART_NR  3
2

3
#define glue(a, b, c) a ## b ## c
4
glue(uart, UART_NR, puts) ("hallo");

und DAS funktioniert jetzt nicht mehr.
Warum?
Weil die Auswertereihenfolge verkehrt ist. Der Präprozessor setzt mit 
diesen Angaben einen Aufruf der Funktion
  uartUART_NRputs
zusammen. D.h. UART_NR wurde nicht ausgewertet. Und genau da kommt jetzt 
der Zwischenschritt über ein anderes Makro ins Spiel. Sein einziger 
Zweck ist es, eine Schicht einzuziehen, in der der Präprozessor 
eventuelle Argumente, die ihrerseits wieder Makros sind, ersetzen kann 
und erst DANACH das Token Pasting erfolgen soll.

#define glue(a, b, c) glue2(a,b,c)

 glue(uart, UART_NR, puts)

wird zu

 glue2( uart, UART_NR, puts )

dann werden die Argumente Makro-Ersetzt

 glue2( uart, 3, puts )

und erst danach wird wieder nachgesehen, ob es für glue2 eine 
Makroersetzung gibt.
Und dann klappts auch mit Argumenten, die ihrerseits Makros sind.
#2703072
Lesenswert?

Stephan R. schrieb:
> Okay, dreimal gelesen, akzeptiert.
> Ist es ein Versäumnis der C-Entwicklung, diese Makro-Umsetzung
> automatisch oder per Befehl durchzuführen?

Nö.
Es ist einfach nur so definiert worden, dass die Argumente zu ## nicht 
vor der Zusammensetzung Makro-ersetzt werden. Das ist alles.

Ein
1
#define CHECK_AA foo
2
#define CHECK_BB bar
3

4
#define CALL_IT(nr) CHECK_ ## nr
5

6
...
7

8
  CALL_IT( AA )();

baut einen Funktionsaufruf der Funktion foo zusammen. Unabhängig davon, 
ob es davor ein
1
#define AA 5
gab oder nicht. Es hat halt immer alles 2 Seiten.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren