app.c:123:45: error: ISO C99 requires rest arguments to be used [-Werror]
2
LOG ("bla");
Ich habe versucht die Code-Stelle mit '#pragma GCC diagnostic'
auszustellen, aber ohne Erfolg.
Ist vielleicht "-Werror" hier fehlplatziert?
Oder wie kann ich das hinbiegen, ohne das LOG macro zu ändern und
-pendantic und -std=c99 eingeschaltet zu lassen?
Danke
Erst -pedantic einschalten und dann jede Menge GCC-spezifische #pragma's
verwenden? Klingt leicht sinnlos.
Dein Vorhaben funktioniert in Standard-C halt nicht. Entweder
GCC-Erweiterungen erlauben, oder auf den Zeilenumbruch verzichten:
Kaj schrieb:> Compiliert bei mir total super.
Dann versuch das mal mit "-pedantic" aktiviert, oder einem Compiler der
nicht die GCC-Extensions hat, nämlich diese:
https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Andere Compiler unterstützen das ", ## __VA_ARGS__" nicht
notwendigerweise.
olpo schrieb:> Oder wie kann ich das hinbiegen, ohne das LOG macro zu ändern und> -pendantic und -std=c99 eingeschaltet zu lassen?
Garnicht. Du verwendest eine Spracherweiterung, willst aber striktes
C99. Entscheide dich mal!
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Dr. Sommer schrieb:> oder einem Compiler der> nicht die GCC-Extensions hat
Warum? Hier ist expliziet vom GCC die rede...
Das einzige was bemängelt wird ist, wenn LOG() außer der Nachricht
keinen weiteren parameter hat.
1
Warnung: ISO C99 requires at least one argument for the "..." in a variadic macro
2
LOG("Hello World!");
3
^
Das eigentliche Problem, das der TO hier hat, ist das er ein Leerzeichen
zwischen LOG und den Klammern hat.
Kaj schrieb:> Warum? Hier ist expliziet vom GCC die rede...
Naja, welchen Sinn hätte -pedantic wenn man nicht beabsichtigt, dass der
Code auch auf andere Compiler portierbar sein soll? Und andere Compiler
können das ", ## __VA_ARGS__" halt nicht.
Kaj schrieb:> Das einzige was bemängelt wird ist, wenn LOG() außer der Nachricht> keinen weiteren parameter hat.
Weil das auch eine GCC-Extension ist... Dass GCC die erste nicht
anmeckert trotz -pedantic ist vermutlich ein Bug/Missing Feature.
g457 schrieb:> ..nicht nett, aber es geht.
Ah, clever. Aber fies :)
Dr. Sommer schrieb:> Naja, welchen Sinn hätte -pedantic wenn man nicht beabsichtigt, dass der> Code auch auf andere Compiler portierbar sein soll?
Keine Ahnung, frag den TO :-)
g457 schrieb:> Dann hast Du die falschen Compileroptionen benutzt (oder den falschen> Compiler).
Nein.
Ohne das Leerzeichen:
main.c:8:5: Anmerkung: bei Substitution des Makros »LOG«
77
LOG("Hello World! %i", 56);
Johann L. schrieb:> Nö.
Dann erklär mir doch bitte, warum mein GCC kein Error wirft, wenns doch
angeblich nicht funktionieren dürfte...
Irgendwo scheinen Theorie und Praxis ja außeinander zu driften...
Kaj schrieb:> Johann L. schrieb:>> Nö.> Dann erklär mir doch bitte, warum mein GCC kein Error wirft, wenns doch> angeblich nicht funktionieren dürfte...
Kann ich dir nicht sagen.
> Das ist die einzige Warnung die kommt.
Sehr schön, geht ja doch - um genau die Meldung gehts doch. Mach noch
ein -Werror dazu und Du bekommst Deinen Fehler.
g457 schrieb:> Sehr schön, geht ja doch - um genau die Meldung gehts doch. Mach noch> ein -Werror dazu und Du bekommst Deinen Fehler.
Hupsi, lesen und so... :-(
Ändert aber nichts daran, dass im eingangspost trotzdem das Leerzeichen
falsch ist :P
Die Warnung leigt aber an der falschen benutzung des Makros.
Mach ein zweites Makro und alles ist schön.
Der TO hat nicht einmal gezeigt wie er das Makor benutzt. Wenn er sein
Makro richtig benutzt (mit zusätzlichen Argumenten!), gibt es beim
compilieren auch keine warnung/fehler. ganz einfach.
olpo schrieb:> Oder wie kann ich das hinbiegen, ohne das LOG macro zu ändern und> -pendantic und -std=c99 eingeschaltet zu lassen?
Das Makro richtig benutzen.
Wenn du keine zusätzlichen Argumente hast, einfach einen Leerstring
anhängen und alles ist schick und du kommst mit nur einem Makro aus und
der Compiler hält die klappe.
Nicht das schönste, aber es könnte schlimmer sein.
Danke soweit.
Eine Kompiler-unabhängige Lösung fuer '##__VA_ARGS__' gibt es ja nicht,
oder?
Und weiß denn noch jemand, warum das Ausschalten des Warning nicht
klappt?
olpo schrieb:> Eine Kompiler-unabhängige Lösung fuer '##__VA_ARGS__' gibt es ja nicht,> oder?
Doch, allerdings erst seit 1999. Da es verbreitete Compiler gibt, die
auf dem Stand von 1989 stehen geblieben sind, geht es trotzdem nicht mit
jedem Compiler.
Rolf M. schrieb:> olpo schrieb:>> Eine Kompiler-unabhängige Lösung fuer '##__VA_ARGS__' gibt es ja nicht,>> oder?>> Doch, allerdings erst seit 1999.
Mach mich schlau. Das ist doch eine GCC-Erweiterung?
Johann L. schrieb:> Mach mich schlau. Das ist doch eine GCC-Erweiterung?
Aus ISO C99:
"If the identifier-list in the macro definition does not end with an
ellipsis, the number of arguments (including those arguments consisting
of no preprocessing tokens) in an invocation of a function-like macro
shall equal the number of parameters in the macro definition. Otherwise,
there shall be more arguments in the invocation than there are
parameters in the macro definition (excluding the ...). There shall
exist preprocessing token that terminates the invocation.
The identifier __VA_ARGS__ shall occur only in the replacement-list of
a function-like macro that uses the ellipsis notation in the arguments."
und
"An identifier __VA_ARGS__ that occurs in the replacement list shall
be
treated as if it were a parameter, and the variable arguments shall form
the preprocessing tokens used to replace it."
Sowie:
Finally, to show the variable argument list macro facilities:
1
#define debug(...) fprintf(stderr, __VA_ARGS__)
2
#define showlist(...) puts(#__VA_ARGS__)
3
#define report(test, ...) ((test)?puts(#test):\
4
printf(__VA_ARGS__))
5
6
debug("Flag");
7
debug("X = %d\n",x);
8
showlist(Thefirst,second,andthirditems.);
9
report(x>y,"x is %d but y is %d",x,y);
results in
1
fprintf(stderr,"Flag");
2
fprintf(stderr,"X = %d\n",x);
3
puts("The first, second, and third items.");
4
((x>y)?puts("x>y"):
5
printf("x is %d but y is %d",x,y));
Man beachte, daß da kein ## vor dem __VA_ARGS__ steht.
Rolf M. schrieb:> Johann L. schrieb:>> Mach mich schlau. Das ist doch eine GCC-Erweiterung?>> Aus ISO C99: [...]> Finally, to show the variable argument list macro facilities:>
1
#define debug(...) fprintf(stderr, __VA_ARGS__)
> Man beachte, daß da kein ## vor dem __VA_ARGS__ steht.
Aber der Witz ist doch gerade das ## in Verbindung mit dem , vor dem ##:
Falls __VA_ARGS__ nicht gegeben ist, entfernt der Präprozessor das
Komma!
Aus "func(msg, ##__VA_ARGS__)" wird also "func(msg)" ohne das dann
überflüssige ,
Wo siehst du so ein Feature im Standard?
Johann L. schrieb:> Aber der Witz ist doch gerade das ## in Verbindung mit dem , vor dem ##:> Falls __VA_ARGS__ nicht gegeben ist, entfernt der Präprozessor das> Komma!
Ok, dann habe ich die Frage missverstanden.
Das würde ich dann so lösen,w ie in
Beitrag "Re: (pedantic) Warning ausschalten: ## __VA_ARGS__" beschrieben.
Na gut, dann ist das zur Zeit nur GCC spezifisch.
Aber noch mal zu meiner anderen Frage:
olpo schrieb:> Und weiß denn noch jemand, warum das Ausschalten des Warning nicht> klappt?
olpo schrieb:> Aber noch mal zu meiner anderen Frage:>> olpo schrieb:>> Und weiß denn noch jemand, warum das Ausschalten des Warning nicht>> klappt?
Weil die Warnung/Fehler erst bei der Nutzung des Makros auftritt, aber
nicht bei der Definition, wo du dein #pragma aber dran geschrieben
hast...
olpo schrieb:> Und weiß denn noch jemand, warum das Ausschalten des Warning nicht> klappt?
Das ist eine Frage für die GCC Mailing-Liste gcc-help@gcc.gnu.org
Falls du dort nachfragst, bring bitte einen funktionierenden Testfall
mit anstatt geschwärzten Code wie
>
1
#pragma GCC diagnostic push
2
>#pragmaGCCdiagnosticwarning"-Werror"
3
>...
4
>#pragmaGCCdiagnosticpop
Dort wird dir im Gegensatz zu hier nämlich niemand die Würmer aus der
Nase ziehen.
Dann gibts auch keine Warnung.
Aus diesem Grund halte ich auch das erste C-Programm von K&R
printf ("Hello, World\n");
für einen ziemlichen Missgriff. Didaktisch klüger wäre entweder ein
puts ("Hello, World");
gewesen. Oder wenn es wirklich um printf() und die formatierte Ausgabe
gegangen wäre, dann halt:
printf ("%s", "Hello, World\n");
Meinetwegen auch noch eine Abart
printf ("Hello %s\n", "World");
für Fortgeschrittene.
Aus diesem Grund benutze ich niemals printf & Co (sprintf, fprintf) ohne
Format-String. Für solche Trivialfunktionen gibt es Alternativen wie
z.B. puts() oder fputs().
Dem TO kann ich nur raten, zwei Macros anzulegen, nämlich LOG_PRINTF()
und LOG_PUTS(). Dann ist klar, wann welches zu benutzen ist: