The key point with C macros is to use them properly. In my mind there are three categories (not considering using them just to give descriptive names to constants)
- As a shorthand for piece of codes one doesn't want to repeat
- Provide a general use function
- Modify the structure of the C language (apparently)
In the first case, your macro will live just within your program (usually just a file) so you can use macros like the one you have posted that is not protected against double evaluation of parameters and uses {...};
(potentially dangerous!).
In the second case (and even more in the third) you need to be extremely careful that your macros behave correctly as if they were real C constructs.
The macro you posted from GCC (min and max) is an example of this, they use the global variables _a
and _b
to avoid the risk of double evaluation (like in max(x++,y++)
) (well, they use GCC extensions but the concept is the same).
I like using macros where it helps to make things more clear but they are a sharp tool! Probably that's what gave them such a bad reputation, I think they are a very useful tool and C would have been much poorer if they were not present.
I see others have provided examples of point 2 (macros as functions), let me give an example of creating a new C construct: the Finite state machine. (I've already posted this on SO but I can't seem to be able to find it)
#define FSM for(;;)
#define STATE(x) x##_s
#define NEXTSTATE(x) goto x##_s
that you use this way:
FSM {
STATE(s1):
... do stuff ...
NEXTSTATE(s2);
STATE(s2):
... do stuff ...
if (k<0) NEXTSTATE(s2);
/* fallthrough as the switch() cases */
STATE(s3):
... final stuff ...
break; /* Exit from the FSM */
}
You can add variation on this theme to get the flavour of FSM you need.
Someone may not like this example but I find it perfect to demonstrate how simple macros can make your code more legible and expressive.