[so] [Tech Q] Print debugging
Adrian Scoica
adrian.scoica at gmail.com
Sun Mar 6 17:17:14 EET 2011
>
> ---
> static enum {
> FALSE = 0,
> TRUE
> } debug = TRUE;
>
> ....
>
> /* undeva intr-o functie */
>
> if (debug == TRUE)
> printf("debug message\n");
> ....
Problema la metoda asta (pe langa faptul ca are 2 linii) este
comparatia. Chiar daca vei compila codul intr-o configuratie "release"
(in care nu se mai face testing), la fiecare apel de functie, se
efectueaza o instructiune in plus (si care mai e si jump pe deasupra).
O metoda mai eleganta este sa definesti un macro de genul:
#ifdef _DEBUG
#define LOG(a) (std::cerr << (a) << "\n")
#else
#define while(0)
#endif
Poate fi si mai complicat, dar nu este relevant acum.
Se observa ca lipseste aici ";" pentru ca vreau sa ma forteze
compilatorul sa pun ";" dupa LOG(a); - asa o sa arate mai normal
codul.
while(0) este pus acolo din cauza unei smecherii de sintaxa. Daca
aveai in codul orginal:
if (x == 5) LOG("X ia valoarea 5"); else x=6;
si compilezi fara _DEBUG, atunci obtii
if (x == 5) while(0); else x = 6;
oricum compilatorul scoate while(0) de acolo, nu produce overhead.
Putea la fel de bine sa fie si for(;0;) sau do { } while(0).
NU putea sa fie in schimb if(0), pentru ca s-ar fi reinterpretat
else-ul de mai jos ca fiind al lui.
De asemenea, in C++ am pus paranteze in jurul lui (a) din macro din
motive de chaining. De exemplu, daca as vrea sa scriu LOG(s <<
arbore), unde s este un obiect de tip stringstream sau string, si
arbore e un arbore de parsare definit de mine, atunci se executa
op<< ( op<< (std::cerr, s), arbore)
si nu cum as fi vrut eu sa fie:
op<< ( std::cer, s << arbore )
Aceleasi smecherii merg si in C, evident, mai putin stream-urile si
operatorii. Se poate defini de exemplu, un macro care sa inlocuiasca
printf();
In aceeasi ordine de idei, se pot defini niveluri diferite de
debugging, care sa activeze sau nu un volum mai mare sau mai mic de
debugging. De exemplu:
_DEBUG_SEM 1 - face logging la arborele semantic, doar erorile generale
_DEBUG_SEM 2 - face logging la arborele semantic, eticheta fiecarui nod
_DEBUG_SEM 3 - face logging de la inceput si pana la sfarsit
Similar ca mai sus, pui intr-un header:
#if _DEBUG_SEM<1
... activeaza LOG_ERR
#if _DEBUG_SEM<2
... activeaza LOG_TAG
#if _DEBUG_SEM<3
... activeaza LOG_FULL
Astfel, poti contola cat de in detaliu vrei sa faci debugging definind
_DEBUG_SEM={1,2.3}. Evident, totul ar trebui protejat de #ifdef [ ...
] #endif.
Pare complicat, dar daca le scrii odata, le poti folosi cu succes in
toate sursele de mai tarziu.
More information about the so
mailing list