Forum: Compiler & IDEs was bewirkt "usart_write_P(PSTR(format) , ## args"


von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

zur Zeit bin ich dabei, mich in die Dekodierung des DCF77-Signals 
einzuarbeiten und bin bei der Suche nach Vorlagen auf Ulrich Radigs 
Variante gestoßen, die eine Ausgabe auf das Terminal schreibt.

http://www.ulrichradig.de/home/index.php/avr/dcf77_uhr
http://www.ulrichradig.de/home/uploads/File/AVR_DCF77/SourceCode.zip

Kann bitte mal jemand diese beiden Zeilen erklären?

in usart.h:
#define usart_write(format, args...)   usart_write_P(PSTR(format) , ## 
args)


in main.c:
    usart_write("%i-%i-%i Time: %i:%i:%i Sync: %i  Rx: %i       \r",
        day,mon,year,hh,mm,ss,flags.dcf_sync,flags.dcf_rx);
    //Wait a schort time


mit freundlichem Gruß

von Georg A. (georga)


Lesenswert?

Das mit den .. bzw. ## ist eine gcc-Erweiterung, die variable 
Argumentanzahl auch für #defines erlaubt. Sinnvoll ist das im 
wesentlichen für printf-Verwandte (wie das usart_write). Der erste 
Parameter des Makros ist der Formatstring, alle weiteren Argumente 
werden mit .. zusammengefasst und im Makrokörper mit ## wieder am Stück 
verwertet.

Der gcc hat übrigens eine ganze Menge Erweiterungen. Solange man in der 
gcc-Welt bleibt (beim AVR noch eher als sonst ;) ist es auch durchaus 
sinnvoll, sich die mal zumindest anzuschauen.

http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html

Das mit dem ../## fällt unter "Variadic Macros".

von Εrnst B. (ernst)


Lesenswert?

Und die zweite Zeile Erklärt:

Christian S. schrieb:
> //Wait a schort time

Das ist ein Tippfehler. Gemeint ist "wait a short time", also "Kurz 
warten".

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Christian S. schrieb:
> in usart.h:
> #define usart_write(format, args...)   usart_write_P(PSTR(format) , ##
> args)

Wichtig ist dabei, daß nach ## kein Zeilenumbruch erfolgt, also
1
#define usart_write(format, args...)   usart_write_P(PSTR(format) , ##args)

Eine weitere GCC-Spezialität ist das Leerzeichen vor dem Komma.  Es 
bewirkt die Entfernung des nachfolgenden Kommas für den Fall, daß keine 
weiteren Argumente folgen.

Damit funktioniert dann auch Code wie usart_write ("Hallo") der zu 
usart_write_P (PSTR("Hallo")) expandiert (*) und eben nicht zu 
usart_write_P (PSTR("Hallo") ,) was einen Compilerfehler nach sich zöge.

Variadische Makros gibt's auch ab C99, allerdings mit anderer Syntax.

(*) Der Übersichtlichkeit wegen ohne expandiertes PSTR Makro.

: Bearbeitet durch User
von Christian S. (roehrenvorheizer)


Lesenswert?

Danke für die Zuschriften. Na, da hat unser geschätzter Ulrich aber 
mächtig in die Trickkiste gegriffen :-) Und eine Funkuhr mit einem 
variadic macro innen drin hat auch nicht jeder...

Variadic Macros != vedische Mythen sind für mich ein neues 
Experimentierfeld, für die man sich doch mal ein eigenes
Übungsprogramm gönnen könnte.
"Variadic Macros: Macros with a variable number of arguments. "

Für jedes

%i

soll anscheinend dann eine der aufgezählten Variablen

day,mon,year,hh,mm,ss,flags.dcf_sync,flags.dcf_rx

der Reihe nach eingesetzt werden, wobei in der Ausgabe noch zusätzlich 
die Worte "Time:" "Sync:" "RX:" erscheinen sollen. Richtig?


Ich melde mich nochmals, wenn es neue Ergerbnisse gibt. Beispielsweise 
könnte man direkt "AVR_DCF77/SourceCode.zip" einmal ausprobieren.



> //Wait a schort time
Den Tapsfühler habe ich zur Belustigung extra mit aus dem Quelltext 
kopiert.


mit freundlichem Gruß

von Oliver S. (oliverso)


Lesenswert?

Christian S. schrieb:
> Danke für die Zuschriften. Na, da hat unser geschätzter Ulrich
> aber
> mächtig in die Trickkiste gegriffen :-) Und eine Funkuhr mit einem
> variadic macro innen drin hat auch nicht jeder...

Nun ja, das ist halt eine Möglichkeit, einen Quelltext auf verschiedene 
Microcontroller anzupassen.

> Variadic Macros != vedische Mythen sind für mich ein neues
> Experimentierfeld, für die man sich doch mal ein eigenes
> Übungsprogramm gönnen könnte.

Ganz ehrlich: die Dinger gehören zu den C-Spezial-Schweinereien, die man 
erst dann anschauen sollte, wenn man normales C mit all seinen Facetten 
wirklich, wirklich, wirklich kann.

Oliver

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
Noch kein Account? Hier anmelden.