[so] [Tech Q] Print debugging

Razvan Deaconescu razvan.deaconescu at cs.pub.ro
Sun Mar 6 17:51:59 EET 2011


On 03/06/2011 05:17 PM, Adrian Scoica wrote:
>>
>> ---
>> 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).

Exact. La cod de "release" îți adaugă comparații suplimentare. Cel mai
bine este să se execute la preprocesare așa cum ai descris mai jos.

> O metoda mai eleganta este sa definesti un macro de genul:
> 
> #ifdef _DEBUG
> #define LOG(a) (std::cerr << (a) << "\n")
> #else
> #define LOG(a) 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.

Corect. Avantajul acestei forme este faptul că poți interacționa din
linia de comandă. Poți folosi -D_DEBUG (gcc) sau /D_DEBUG (MSVC) pentru
a activa "modul debug".

În plus, secvența de mai sus va fi definită într-un header inclus de
modulele C astfel că nu va fi necesară definirea unei funcții sau a unei
variabile în fiecare modul.

În general, numele care încep cu underscore sunt rezervate pentru
biblioteca standard C sau aplicații de sistem. Din acest motiv recomand
DEBUG sau DEBUG_ sau DEBUG__

Pentru C, secvența de mai sus va fi una de forma:
---
#ifdef DEBUG_
#define LOG(a)               \
        fprintf(stderr, a)   \
#else
#define LOG(a)               \
        do { } while (0)     \
#endif
---

Mi se pare mai expresivă forma cu 'do { } while (0)' în așteptarea
caracaterului ; (punct și virgulă)

Există două neajunsuri:

1) Când faci debugging, vrei să nu afișezi doar un mesaj ci, de dorit,
fișierul și linia care a generat mesajul.
2) Nu vrei să afișezi doar un string ci poate o afișare de forma printf.
Adică LOG("x = %d, y = %d\n", x, y);

Ce posibilități există pentru rezolvarea acestor neajunsuri?

> Pare complicat, dar daca le scrii odata, le poti folosi cu succes in
> toate sursele de mai tarziu.

Exact. Un astfel de set de macro-uri sunt utile pentru development la
orice aplicație și îți fac viața ușoară pentru debugging.

Răzvan


More information about the so mailing list