#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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.