Introduction to the C Preprocessor
The C preprocessor is a text substitution tool that runs before the actual compilation begins. It processes all lines beginning with# and performs text replacements, file inclusions, and conditional compilation.
Preprocessor Directives
All preprocessor directives start with# and must appear at the beginning of a line (though whitespace is allowed before the #).
Common directives:
#include- Include files#define- Define macros#undef- Undefine macros#ifdef,#ifndef- Conditional compilation#if,#elif,#else,#endif- More complex conditions#error- Generate compilation error#pragma- Compiler-specific commands
Header Guards
Header guards prevent multiple inclusion of the same header file:- First inclusion:
SIZEis not defined, so#define SIZE 1024executes - Second inclusion:
SIZEis already defined, so the block is skipped - This prevents redefinition errors
Object-like Macros
Object-like macros are simple text replacements without parameters.Defining Constants
SIZE in your code will be replaced with 1024 before compilation.
Mathematical Constants
Benefits of Object-like Macros
Maintainability
Change the value in one place, and it updates everywhere
Readability
SIZE is more meaningful than a magic number like 1024Function-like Macros
Function-like macros take parameters and perform text substitution with those parameters.Absolute Value Macro
- Parameters are enclosed in parentheses:
(x) - The entire macro is enclosed in parentheses
- Uses the ternary operator for conditional logic
Simple Arithmetic Macro
Predefined Macros
C provides several predefined macros that are automatically available:__FILE__ - Current File Name
2-main.c)
Other Predefined Macros
| Macro | Description | Example |
|---|---|---|
__LINE__ | Current line number | 42 |
__DATE__ | Compilation date | "Mar 03 2026" |
__TIME__ | Compilation time | "12:34:56" |
__FUNCTION__ | Current function name | "main" |
Macro vs Function
Macros
Advantages:
- No function call overhead
- Type-independent
- Inline expansion
- Larger code size
- No type checking
- Hard to debug
- Side effects with complex expressions
Functions
Advantages:
- Type checking
- Easier to debug
- Can use pointers and addresses
- Smaller code size
- Function call overhead
- Type-specific
- Not inline (unless specified)
Macro Pitfalls
Side Effects
Solution
Multi-line Macros
For complex macros spanning multiple lines, use backslash (\) for line continuation:
Conditional Compilation
Debug Builds
Platform-specific Code
Best Practices
-
Use UPPERCASE for macro names
-
Always use header guards
-
Parenthesize everything in macros
-
Prefer inline functions for complex logic
-
Document your macros
Common Use Cases
Array Size
Min/Max
Bit Operations
Key Takeaways
- The preprocessor performs text substitution before compilation
- Use object-like macros for constants
- Use function-like macros for simple operations
- Always parenthesize macro parameters and the entire macro
- Avoid side effects in macro arguments
- Use header guards in all header files
- Prefer inline functions for complex logic
Related Topics
Bit Manipulation
Learn about bitwise operations
Structures & Typedef
Master custom data types