Define a macro MAX3 that gives the maximum of three values.
This is what I came up with:
#define MAX3(a,b,c) ( ((a) > (b)) && ((a) > (c)) ) ? (a) : ((b) > (c)) ? (b) : (c)
This is hard to read. Is there a way to write an equivalent macro with if–else statements?
Having an expression-like macro with statements inside is not possible in standard C99 language (because in C99 statements and expressions are deeply different, both syntactically and semantically).
However, GCC (and some other compilers with extensions inspired by GCC, e.g. clang) provides a nice extension for that : statement expressions (the documentation gives an example related to your question). With that extension you could code something like
however that still won’t work if you use that macro like e.g.
I hope you see why it won’t work (name clashes e.g. between the
ainsidebadexand theainsideMAX3macro). So you need a way to have unique names at every invocation of your macro. Again, GCC provides a nice extension for that, the__COUNTER__macro (expanded to a unique number, counting) used with concatenation in the preprocessor.Then you’ll code something like
Then the first invocation of our macro e.g.
MAX3(i++,j++,k++)might expand toMAX3_COUNTED((i++),(j++),(k++),1)which gets expanded into something usinga_1b_1… and the second invocation, e.g.MAX3(a,m,d)expanded asMAX3_COUNTED((a),(m),(d),2)would usea_2b_2etc so is better.And of course, defining a
static inline max3(int a, int b, int c)function is cleaner (in particular because of side effects: yourMAX3macro gives naughty effects and results with a call likeMAX3(i++,j++,k++)etc)The general lesson about this is that you should when possible avoid macro (preferring inline functions), and when you absolutely need macros take care about name clashes and expansions.
Using GCC invoked as
gcc -C -Eshows you the preprocessed form of your program.