Mit GCC extensions, können Sie Makros betrachten, die wie
bool silent;
#define silence(X) ({int _x; quiet(); _x = (X); verbose(); _x; })
#define printf(Fmt,...) \
do{if (!silent) printf(Fmt,##__VA_ARGS__);}while(0)
dass silence
Makro funktionieren würde nur dann, wenn ihr Argument X
ein int
Ausdruck (oder verwenden Sie typeof) Ich gehe davon aus, dass das Ergebnis der printf
ist nie benutzt. Erinnern Sie sich, dass "rekursive" Makros speziell vorverarbeitet werden, das interne Auftreten von printf
(in diesem printf
Makro) wird wortwörtlich ohne Makroexpansion verlassen.
Beachten Sie, dass silence
keine Funktion sein kann (andernfalls wäre das Argument vor dem Aufruf ausgewertet worden). Und Sie müssen GCC statement expressions Erweiterung zu "erinnern" das Ergebnis des Arguments in einer Variablen _x
(Sie könnten diesen Namen mit __COUNTER__
und Präprozessor-Verkettung generieren), um es als Wert von silence
Makroaufruf geben.
Dann müssen Sie Ihre Funktionen quiet()
und verbose()
definieren, vielleicht so etwas wie
void quiet()
{
silent = true;
}
void verbose()
{
silent = false,
}
wenn Sie nicht printf
als Makro definieren möchten, können Sie freopen(3) auf stdout
(vielleicht mit "/dev/null"
usw. verwenden könnte ..) oder tun dup2(2) Tricks (wie suggested by Pascal Cuoq).
Wenn Ihre Codebasis riesig ist und Sie etwas Ernsteres wollen und Tage oder Wochen mit der Arbeit verbringen möchten, ziehen Sie in Betracht, Ihren GCC-Compiler mit einem Plugin oder einer MELT Erweiterung anzupassen (oder bitten Sie jemanden, dies zu tun). Beachten Sie, dass printf
GCC bekannt ist.
In Wirklichkeit sollten Sie Ihr eigenes Makro wie
#define myprintf(Fmt, ...) do{if (!silent) \
printf(Fmt,__VA_ARGS__);}while(0)
definieren und nur myprintf
statt printf
überall verwenden, ist dies ein tragbarer Trick. Natürlich nehme ich an, dass Sie printf
nicht als Funktionszeiger übergeben.
Zum Debuggen, empfehle ich eigentlich
#define dbgprintf(Fmt,...) do{if (wantdebug) \
printf("%s:%d:" Fmt "\n", __FILE__, __LINE__, \
##__VA_ARGS__);}while(0)
und ich verwende dann dbgprintf("i=%d",i)
oder einfach dbgprintf("foo here")
in meinem Code.
Ich verwende ##__VA_ARGS__
, die eine GCC-Erweiterung ist, um no variable arguments zu einem variadic Makro zu akzeptieren. Wenn Sie strikte C99 wollen, werden Sie einfach __VA_ARGS__
sagen und jeder dbgprintf
würde ein Argument nach dem Format benötigen.
Sie könnten auch Ihre eigene printf
Funktion implementieren, aber ich rate davon ab.
(Beachten Sie, dass die Dinge könnte komplexer sein, können Sie fputs
nicht printf
mit drucken ....)
Sie die Funktion nicht nennen ... Was ist Ihre Absicht? –
Es ist Software, fast alles ist möglich. Willst du eine Funktion? Oder ist eine Präprozessor-Methode akzeptabel? Wie wäre es, Code zur Laufzeit zu modifizieren? –
http://chat.stackoverflow.com/rooms/29552/c (Lassen Sie uns darüber diskutieren, aye?) :) – cipher