[TAG] 2-cent Tip - Stringizing a C statement

Neil Youngman ny at youngman.org.uk
Mon Jan 5 17:28:47 MSK 2009


On Monday 05 January 2009 14:06:12 Oscar Laycock wrote:
> I recently discovered you could "stringize" a whole C++ or C statement with
> the pre-processor. For example:
>
> #define TRACE(s) cerr << #s << endl; s
> or:
> #define TRACE(s) printf("%s\n", #s); s
>
> ....
> TRACE(*p = '\0');
> p--;
>
> (I found this in "Thinking in C++, 2nd ed. Volume 1" by Bruce Eckel,
> available for free at www.mindview.net. By the way, it seems a good
> introduction to C++ for C programmers with lots of useful exercises. There
> is also a free, but slightly old, version of the official Qt book (the C++
> framework used in KDE), at
> http://www.qtrac.eu/C++-GUI-Programming-with-Qt-4-1st-ed.zip. It is a bit
> difficult for a C++ beginner, and somewhat incomplete without the
> accompanying CD, but rewarding none the less.)
>
> Bruce Eckel adds: "of course this kind of thing can cause problems,
> especially in one-line for loops:
>
> for(int i = 0; i < 100; i++)
> ?TRACE(f(i));
>
> Because there are actually two statements in the TRACE( ) macro, the
> one-line for loop executes only the first one. The solution is to replace
> the semicolon with a comma in the macro."

Better yet, always use braces with your for/if/else/while statements, even if 
there is only a single line now. It avoids later editing errors and problems 
with "too clever by half macros.

> However, when I try this with a declaration. I get a compiler error:
>
> ??????? TRACE(char c = *p);
>
> s.cpp:17: error: expected primary-expression before 'char'
> s.cpp:17: error: expected `;' before 'char'
>
> I'm not sure exactly why!??

It's obvious. Do the substitution and you get:

cerr <<  char c = *p << endl; char c = *p;

which is obviously garbage. It's never going to work where the statement is a 
declaration.

HTH

Neil Youngman




More information about the TAG mailing list