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?
Stephan R. schrieb: > Das funktioniert "natürlich" nicht, nur wie verschachtelt man #defines > vernuenftig? http://de.wikipedia.org/wiki/C-Pr%C3%A4prozessor#Verkettung_von_Makroparametern
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");
Versuch mal
1 | #define glue2(a, b, c) a ## b ## c
|
2 | #define glue(a, b, c) glue2(a,b,c)
|
3 | glue(uart, 3, puts) ("hallo"); |
Stephan R. schrieb: > Nur warum? Der Präprozessor ist da etwas eigen... (Anders gesagt: Ich nur dass es läuft aber nicht warum.)
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.
Okay, dreimal gelesen, akzeptiert. Ist es ein Versäumnis der C-Entwicklung, diese Makro-Umsetzung automatisch oder per Befehl durchzuführen? (PS: Ich hab vorm Schlafengehen immer ne Fluortablette bekommen- was hat KHB bekommen?)
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.