#define Macros and the Preprocessor

The preprocessor

Before your code is compiled, a helper called the preprocessor reads it. Every line starting with # is an order for the preprocessor:

  • #include <stdio.h>: paste in the contents of stdio.h.
  • #define NAME value: replace every NAME in the code with value.

Think of it like this: The preprocessor is like "find and replace" in a word processor, done automatically just before compiling.

Macros with parameters

A #define can take parameters, like a tiny function:

#include <stdio.h>

#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
    printf("%d\n", SQUARE(7));
    printf("%d\n", MAX(3, 11));
    return 0;
}

Output

49
11

Why all those brackets?

Macros are pure text replacement. Without brackets, strange things happen. Look:

#include <stdio.h>

#define BAD_SQUARE(x) x * x
#define GOOD_SQUARE(x) ((x) * (x))

int main() {
    printf("%d\n", BAD_SQUARE(2 + 3));
    printf("%d\n", GOOD_SQUARE(2 + 3));
    return 0;
}

Output (on your own computer with gcc – the simple C runner in the browser editor can't run this one)

11
25

BAD_SQUARE(2 + 3) becomes 2 + 3 * 2 + 3, which is 11, not 25!

Common mistake: Writing a macro without brackets around each parameter and around the whole thing.

Tip: For anything more than a tiny calculation, write a normal function. Functions are easier to understand and debug.

HOME LABS COMMUNITY DASHBOARD