Chapter 16. Function-like macros
This chapter covers
- Checking arguments
- Accessing the calling context
- Working with variadic macros
- Type-generic programming
We have encountered function-like macros explicitly in section 10.2.1 and also implicitly. Some interfaces in the C standard library are typically implemented by using them, such as the type-generic interfaces in tgmath.h. We also have seen that function-like macros can easily obfuscate our code and require a certain restrictive set of rules. The easiest strategy to avoid many of the problems that come with function-like macros is to only use them where they are irreplaceable, and to use appropriate means where they are replaceable.
Takeaway 16.1
Whenever possible, prefer an inline function to a functional macro.
That is, in situations where we have a fixed number of arguments with a known type, we should provide a proper type-safe interface in the form of a function prototype. Let us suppose we have a simple function with side effects:
unsigned count(void) { static counter = 0; ++counter; return counter; } !@%STYLE%@! {"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":8}],[{\"line\":0,\"ch\":15},{\"line\":0,\"ch\":19}],[{\"line\":1,\"ch\":2},{\"line\":1,\"ch\":8}],[{\"line\":3,\"ch\":2},{\"line\":3,\"ch\":8}]]"} !@%STYLE%@!
Now consider that this function is used with a macro to square a value: