A preprocessor "trick" not mentioned in the article is the use of GNU statement expressions.
The article describes the do {} while(0) trick to make macros look like statements. They can then basically be used like inline void function calls. But what if you want to write a macro to replace an inline function that returns a result?
Statement expressions [1] solve that problem. Now you can finally do this:
int _foo(int x) { return 2 * x; }
#ifdef __DEBUG__
# define foo(x) \({ \
int r = _foo(x); \
printf( \
"foo returned: %d (%s:%d)\n", \
r, __FILE__, __LINE__ \
); \
r; \
})
#else
# define foo _foo
#endif
They are supported by most popular compilers which are not made by Microsoft (including GCC and clang).