In C99 gibt es ein bekanntes Problem mit leeren Argumenten für verschiedene Makros.
Beispiel:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
Die Verwendung von BAR()
oben ist gemäß dem C99-Standard in der Tat falsch, da es erweitert wird auf:
printf("this breaks!",);
Beachten Sie das nachfolgende Komma - nicht funktionsfähig.
Einige Compiler (z. B. Visual Studio 2010) werden dieses nachfolgende Komma für Sie stillschweigend entfernen. Andere Compiler (zB: GCC) unterstützen das Setzen ##
vor __VA_ARGS__
, wie folgt:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
Aber gibt es einen standardkonformen Weg, um dieses Verhalten zu erreichen? Vielleicht mehrere Makros verwenden?
Im Moment ##
scheint die Version ziemlich gut unterstützt zu sein (zumindest auf meinen Plattformen), aber ich würde wirklich lieber eine standardkonforme Lösung verwenden.
Präventiv: Ich weiß, ich könnte nur eine kleine Funktion schreiben. Ich versuche dies mit Makros zu tun.
Bearbeiten : Hier ist ein Beispiel (wenn auch einfach), warum ich BAR () verwenden möchte:
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
Dadurch wird meinen BAR () - Protokollierungsanweisungen automatisch eine neue Zeile hinzugefügt, vorausgesetzt, es fmt
handelt sich immer um eine C-Zeichenfolge in doppelten Anführungszeichen. Die neue Zeile wird NICHT als separates printf () gedruckt. Dies ist vorteilhaft, wenn die Protokollierung zeilengepuffert ist und asynchron aus mehreren Quellen stammt.
__VA_OPT__
Schlüsselwort basiert . Dies wurde bereits von C ++ "übernommen" , daher gehe ich davon aus, dass C diesem Beispiel folgen wird. (
BAR
statt überhaupt verwendenFOO
?