
Tips on writing C macros - adamo
http://www.commonsense4commonpeople.net/2008/11/tips-on-writing-c-macros.html
======
paulbaumgart
What's that nonsense with the do-while loop? Why not just enclose the macro
body in both curly braces and then in parentheses?

Also, more useful (GCC only, though) than just enclosing parameters in
parentheses, because it makes macros side-effect safe:
[http://en.wikipedia.org/wiki/C_preprocessor#Multiple_evaluat...](http://en.wikipedia.org/wiki/C_preprocessor#Multiple_evaluation_of_side_effects)
Of course, in the macro in the article, the first 2 parameters need to be
modifiable lvals anyway, so for those the whole deal with parentheses and the
typeof construct is a moot point.

I'd write the proposed macro as:

    
    
      #define MYMACRO(a,b,c) \
        ({ \
          typeof (c) _c = (c); \
          a = b + _c; \
          b = _c * 2; \
        })

~~~
tb
The do-while "nonsense" is a pretty standard construct, so much so that I'd
never seen your approach - which I admit looks nicer. How well is that
supported across different compilers? Is it part of C99, for example?

~~~
paulbaumgart
No, it's not in C99:
[http://www.redhatrenewals.com/docs/manuals/enterprise/RHEL-4...](http://www.redhatrenewals.com/docs/manuals/enterprise/RHEL-4-Manual/gcc/c-extensions.html)

Admittedly I have little experience with compilers other than GCC, but all
things considered, I'd shy away from using anything but really basic macros
without the compound-statement-in-parens and typeof() extensions that GCC
provides.

Perhaps I spoke too harshly, calling it "nonsense". :-)

~~~
paulbaumgart
So, just to follow up, I saw that the OCUnit macros (
<http://www.sente.ch/software/ocunit/> ) are all using defined using the
do...while(0) guard.

I was wrong. It's the more platform independent way to do things.

For code that's only ever going to be compiled with GCC, though, the statement
expression method is cleaner, I think.

------
dspeyer
> Passing MyArray[x+3] as a macro argument would lexically copy this
> expression in multiple locations in the macro expansion, causing the
> generated code to needlessly evaluate *(Myarray+x+3) again and again and
> again.

Wouldn't any decent optimizing compiler eliminate those common subexpressions?
That's one of the basics, isn't it?

Of course, if you're in a tight enough loop to worry about that, check the
assembly by hand.

------
_sh
How do you step through multi-line macros in a debugger?

~~~
shadytrees
GDB has some bare-essentials macro support for the preprocessor macros, and I
imagine people can get fancier with their own GDB scripts and functions.

<http://sourceware.org/gdb/current/onlinedocs/gdb_11.html>

------
ori_b
Use inline functions instead of macros whenever possible. They don't have all
the tricky gotchas, and they generally have no performance impact over macros.

------
yvueywa
Tip 1, don't

Tip 2, see tip 1

~~~
neilc
That is silly; there are plenty of situations in which macros are useful in C.
I'd be inclined to avoid complex multi-line macros that multiply-evaluate
their arguments unless there's a compelling need for them, however.

