On Sun, 06 Jul 2003, Robert Collins wrote:
> #define DoDebug(CONTENT) { \
>         Debug::getDebugOut() << CONTENT; \
>         Debug::finishDebug(); }
> #define debugs(SECTION, LEVEL) \
>         if ((Debug::level = (LEVEL)) > Debug::Levels[SECTION]) \
>           (void) 0;  \
>         else \
>           DoDebug

I would wrap the DoDebug macro definition in the conventional
"do { ... } while (0)" construct, so that trailing semicolons work
as expected.  The debugs macro can't be handled this way.

        #define DoDebug(CONTENT) \
            do { \
                Debug::getDebugOut() << CONTENT; \
                Debug::finishDebug(); \
            } while (/*CONSTCOND*/ 0)
        #define debugs(SECTION, LEVEL) \
                if ((Debug::level = (LEVEL)) <= Debug::Levels[SECTION]) \
                  (void) 0;
                else \
                  DoDebug

> /* The goal is:
>  * debugs(x,y)(a << b << c)
>  * to evaluate to
>  * if ((Debug::level = (LEVEL)) > Debug::Levels[SECTION])
>  *   (void) 0;
>  * else
>  *   { Debug::getDebugOut() << a << b << c; Debug::finishDebug();}
>  */ 

My way, the caller must supply a trailing semicolon in

     debugs(x,y)(a << b << c);

whereas your way the caller is not allowed to supply a trailing semicolon.
Supplying the trailing semicolon is more natural; it makes use of the macro
more closely resemble use of an ordinary function.

--apb (Alan Barrett)

Reply via email to