The Translation Pipeline (Phase 4)
The C Preprocessor (CPP) is a separate program that runs before the actual compilation. It does not understand C syntax; it performs Token-based Text Substitution. Directives for the preprocessor always start with a #.
File Inclusion: #include
#include <file>: Searches the system include directories (Standard Library).#include "file": Searches the local project directory first, then fallback to system paths.
The Include Guard Pattern: To prevent a header from being included multiple times (which causes “redefinition” errors), every header file should use an include guard:
#ifndef MY_HEADER_H
#define MY_HEADER_H
// Your declarations here
#endif
Macros: #define
Macros allow you to define symbols that the preprocessor will swap for their replacement text wherever they appear.
1. Simple Constants
#define MAX_BUFFER 1024
2. Function-like Macros
Macros can take arguments. However, because they are just text replacement, they are dangerous.
#define SQUARE(x) x * x
// SQUARE(5 + 1) becomes 5 + 1 * 5 + 1 = 11 (Wrong!)
// Fixed: #define SQUARE(x) ((x) * (x))
Conditional Compilation
The preprocessor can “strip out” code blocks based on specific conditions. This is the primary way C achieves Portability across different Operating Systems.
#ifdef _WIN32
// Windows-specific code
#elif __linux__
// Linux-specific code
#endif
Stringification and Token Pasting
The preprocessor provides two special operators:
#(Stringification): Converts a macro argument into a string literal.##(Token Pasting): Merges two tokens into one.
#define DEBUG_PRINT(var) printf(#var " = %d\n", var)
int speed = 60;
DEBUG_PRINT(speed); // Expands to: printf("speed" " = %d\n", speed);
Include Guards
#ifndef HEADER_H HEADER_H // ... code ... #endif
The Pitfalls: Macros vs. inline
Modern C often prefers inline functions over macros because:
inlinefunctions obey Scope rules.- They are Type-safe.
- They avoid Multiple Evaluation side effects.
Interactive Lab
Waiting for signal...