$ overview
overview/0x0E·Working With The System

The Preprocessor

#include, #define, and macros — text substitution before compilation.

Before your code is compiled, it passes through the preprocessor — a text-substitution step that handles every line starting with #. It doesn't understand C; it just rewrites your source file according to a small set of directives, and hands the result to the compiler.

#include

You've used this since chapter 0x00. It literally pastes the contents of another file in place:

include.c
1#include <stdio.h> // a standard library header, in angle brackets
2#include "helpers.h" // a header file of your own, in quotes

Angle brackets tell the compiler to look in the system's standard include paths; quotes look in your project first.

#define: constants and macros

define.c
1#define MAX_USERS 100
2#define PI 3.14159
3 
4int users[MAX_USERS];
5float area = PI * radius * radius;

Every occurrence of MAX_USERS is replaced with 100 before compilation even begins — the compiler never sees the name MAX_USERS at all. const variables (0x01) are usually preferred for simple constants today, since they have a real type the compiler can check.

Function-like macros

macro.c
1#define SQUARE(x) ((x) * (x))
2 
3int result = SQUARE(5); // expands to ((5) * (5))
warning: Macros are pasted text, not function calls
Without parentheses around both the parameter and the whole expression, operator precedence rewrites the macro in surprising ways. Always parenthesize every parameter, and the full expansion, in a function-like macro.
macro-trap.c
1#define SQUARE(x) x * x
2 
3SQUARE(2 + 3); // expands to 2 + 3 * 2 + 3 → 11, not 25

Conditional compilation

#ifdef and related directives include or exclude code before compilation, commonly used for platform-specific code or debug-only logging:

ifdef.c
1#define DEBUG
2 
3#ifdef DEBUG
4 printf("Debug: entering main\n");
5#endif

Include guards

Header files use a guard to prevent being pasted into the same file twice — essential once a project has multiple files including the same header, covered next in 0x0F:

guard.h
1#ifndef HELPERS_H
2#define HELPERS_H
3 
4// declarations go here
5 
6#endif