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.

<tgmath.h>
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:

16.1. How function-like macros work

16.2. Argument checking

16.3. Accessing the calling context

16.4. Default arguments

16.5. Variable-length argument lists

16.5.1. Variadic macros

16.5.2. A detour: variadic functions

16.6. Type-generic programming

Summary