variadic-makros und c standards, wo fuehrt das alles hin?
-
Hallo Zusammen,
Laut gcc gibt es 3 moegliche bzw. 4 Arten von variadic macros Implementierungen.
1. c99 vmacros
2. gnuc vmacros
3. c++ vmacros
4. c89 vmacros(welche nicht empfohlen wird).1. So die c99 standard beschreibt eine variadic macro als folgende:
#define logger(level, fmt, ...) print_sth(level, fmt, __VA_ARGS__) /* und*/ print_sth(enum level_type level, char* fmt, ...){ va_list list_p ; printf("%d",level); va_start(list_p, fmt) ; vprintf(fmt, list_p); }
Es gibt hier eine dangling comma problem! Es kann keine logger Anweisung wie
logger(lev2, "level 2 print:\n") ;
ausgefuehrt werden. Man bekommt eine ,
main.c:30: error: expected expression before ‘)’ token
, kann auch mit gcc -E nachgeprueft werden.
2. gnu-c variadic macros sind nicht iso c standard, das heisst wenn so eine
macro mit einem anderen Compiler als gcc kompiliert wird, kann es probleme
geben..3. Ausser c99 und gnu-c Variante, die gnu compiler collection bietet noch die
c++ variadic macros an, wo die dangling comma problem durch ## verhindert
wird.Jetzt meine Frage, wenn ich c in c99 standard schreibe, heisst es
dass ich default ein dangling comma Problem habe? Wenn ja, wozu hat man dann
eine fehlerhafte Standard in die Sprache hinzugefuegt? Wie geht man damit um?Danke,
-
Sicher, dass logger(lev2, "level2",); nicht geht?
-
Sicher? schrieb:
Sicher, dass logger(lev2, "level2",); nicht geht?
nach deiner Hinweis noch mal getestet, aber leider nein (gcc version 4.1).
-
Hallo,
Jetzt meine Frage, wenn ich c in c99 standard schreibe, heisst es
dass ich default ein dangling comma Problem habe?Ja, das Problem wirst du haben, obwohl einige Compiler Erweiterungen derart haben, dass der Präprozessor das Komma entfernt, wenn es "nicht nötig" ist.
Wenn ja, wozu hat man dann
eine fehlerhafte Standard in die Sprache hinzugefuegt?Ist kein fehlerhafter Standard, man muss nur wissen, was man darf und was nicht.
Wie geht man damit um?
Immer ein Argument angeben, wenn man variadic macros verwenden will.
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
Hallo,
Jetzt meine Frage, wenn ich c in c99 standard schreibe, heisst es
dass ich default ein dangling comma Problem habe?Ja, das Problem wirst du haben, obwohl einige Compiler Erweiterungen derart haben, dass der Präprozessor das Komma entfernt, wenn es "nicht nötig" ist.
Probe-Nutzer
Danke fuer die Antwort. Nun, wie kommt es dazu, dass "printf" und ihre Freunde
an sich so ein Problemchen nicht haben? Wie werden die print-Familie
implementiert?Wegen "einige Compilern", die das Komma entfernen sollen.. hast du da Namen? auch
ptr's sind Wilkommen ;).Danke & Gruss,
-
printf() ist ja eine Funktion und kein Makro, das heißt die Aufgabe wird vom Compiler und nicht vom Präprozessor erledigt. Und es gelten natürlich auch andere Regeln.
Stört es dich so sehr am Ende noch ein Komma hinzuschreiben? Find ich jetzt nicht wirklich schlimm.
-
Nun, wie kommt es dazu, dass "printf" und ihre Freunde
an sich so ein Problemchen nicht haben? Wie werden die print-Familie
implementiert?Weil das Funktionen sind, die mit Hilfe der Ellipse:
http://msdn.microsoft.com/en-us/library/k64h826d(VS.80).aspx
einem vom Compiler (nicht vom Präprozessor) unterstützten Sprachmerkmal, implementiert sind.
Wegen "einige Compilern", die das Komma entfernen sollen.. hast du da Namen?
z.B. der hier:
MfG,
Probe-Nutzer
-
Probe-Nutzer schrieb:
Weil das Funktionen sind, die mit Hilfe der Ellipse:
http://msdn.microsoft.com/en-us/library/k64h826d(VS.80).aspx
einem vom Compiler (nicht vom Präprozessor) unterstützten Sprachmerkmal, implementiert sind.
z.B. der hier:
MfG,
Probe-Nutzer
Tippgeber schrieb:
Stört es dich so sehr am Ende noch ein Komma hinzuschreiben? Find ich jetzt nicht wirklich schlimm.
Interresant.. ich werde meine autotools entsprechend
auf compiler-unterschied hinweisen und meine Kode aendern.Ne, iz nicht schlimm, nun liebe printf hat keine macken aber doch
entsteht eine schon wenn man einen wrapper um sie herumpackt.. Das wollte
ich vermeiden..;)
-
Du kannst ja auch einfach eine Funktion logger() schreiben, statt dem Makro, dann hast du alles so wie du willst. Und Fehlermeldungen bei Syntaxfehler mit logger() werden auch richtig angezeigt, anstelle des gewrappten Funktionsaufrufs.