Con GCC extensions, si potrebbe prendere in considerazione che le macro come
bool silent;
#define silence(X) ({int _x; quiet(); _x = (X); verbose(); _x; })
#define printf(Fmt,...) \
do{if (!silent) printf(Fmt,##__VA_ARGS__);}while(0)
che silence
macro avrebbe funzionato solo se il suo argomento X
è un'espressione int
(o usare typeof) Suppongo inoltre che il risultato di printf
non è mai Usato. Ricordiamo che le macro "ricorsive" sono appositamente pre-elaborate, l'occorrenza interna di printf
(in quella macro printf
) è lasciata testualmente senza macroespansione.
noti che silence
non può essere una funzione (in caso contrario, il suo argomento sarebbe stata valutata prima di chiamare). E hai bisogno dell'estensione GCC statement expressions per "ricordare" il risultato dell'argomento in alcune variabili _x
(potresti generare quel nome usando __COUNTER__
e la combinazione del preprocessore), per restituirlo come valore della chiamata di macro silence
.
allora avete bisogno di definire le funzioni e le quiet()
verbose()
, forse qualcosa di simile
void quiet()
{
silent = true;
}
void verbose()
{
silent = false,
}
se non si desidera definire printf
come la macro, è possibile utilizzare il freopen(3)stdout
(magari con "/dev/null"
etc. ..) o fare trucchi dup2(2) (come suggested by Pascal Cuoq).
Se la base di codice è enorme, e si desidera qualcosa di più serio e sono disposti a spendere giorni o settimane di lavoro, considerano la personalizzazione del compilatore GCC con un plugin o un'estensione MELT (o chiedere a qualcuno di farlo). Si noti che printf
è noto a GCC.
In realtà, si dovrebbe definire il proprio macro come
#define myprintf(Fmt, ...) do{if (!silent) \
printf(Fmt,__VA_ARGS__);}while(0)
e basta usare myprintf
invece di printf
ovunque, questo è un trucco portatile. Naturalmente, presumo che non stiate passando a printf
come puntatore a funzione.
Per il debug, in realtà ho consiglio
#define dbgprintf(Fmt,...) do{if (wantdebug) \
printf("%s:%d:" Fmt "\n", __FILE__, __LINE__, \
##__VA_ARGS__);}while(0)
e poi io uso dbgprintf("i=%d",i)
o semplicemente dbgprintf("foo here")
nel mio codice.
Sto usando ##__VA_ARGS__
che è un'estensione GCC per accettare no variable arguments in una macro variabile. Se si desidera un C99 rigoroso, si dirà semplicemente __VA_ARGS__
e ogni dbgprintf
avrà bisogno di un argomento dopo il formato.
È anche possibile ri-implementare la propria funzione printf
, ma non è consigliabile farlo.
(Si noti che le cose potrebbero essere più complesse, è possibile stampare utilizzando fputs
non printf
....)
Non chiamare la funzione di ... Qual è la vostra intenzione? –
È un software, quasi tutto è possibile. Vuoi una funzione? O è accettabile un metodo per il preprocessore? Che ne dici di modificare il codice in fase di runtime? –
http://chat.stackoverflow.com/rooms/29552/c (Discutiamo laggiù, sì?) :) – cipher