Preprocessor Directives — #define, #include, Macros
468 words
2 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Preprocessor Directives — #define, #include, Macros ## 🎯 Learning Objectives - Use #define for symbolic constants and macros - Create function-like macros with parameters - Use conditional compilation (#ifdef, #ifndef) - Understand the preprocessor execution model * * * ## 1. Preprocessor Overview The preprocesso...

Preprocessor Directives — #define, #include, Macros
🎯 Learning Objectives
- Use #define for symbolic constants and macros
- Create function-like macros with parameters
- Use conditional compilation (#ifdef, #ifndef)
- Understand the preprocessor execution model
1. Preprocessor Overview
The preprocessor runs before compilation. It performs text substitution based on directives.
1.1 Key Directives
| Directive | Purpose |
|---|---|
#include | File inclusion |
#define | Macro definition |
#undef | Remove macro |
#ifdef / #ifndef | Conditional compilation |
#if / #else / #elif / #endif | Conditional with expressions |
#pragma | Compiler-specific instructions |
#error | Generate compile error |
#line | Line number control |
2. Macros
2.1 Object-like Macros
c#define PI 3.14159265 #define MAX_BUFFER_SIZE 4096 #define ERROR_MSG "An error occurred"
2.2 Function-like Macros
c#define SQUARE(x) ((x) * (x)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
Important: Parentheses are critical!
c#define BAD_SQUARE(x) x * x int result = BAD_SQUARE(2 + 3); // 2 + 3 * 2 + 3 = 11 (WRONG!) // FIX: #define SQUARE(x) ((x) * (x)) // SQUARE(2+3) = ((2+3) * (2+3)) = 25
3. Conditional Compilation
c#define DEBUG 1 #ifdef DEBUG printf("Debug: x = %d, y = %d\n", x, y); #endif // Platform-specific code #ifdef _WIN32 #include <windows.h> #elif defined(__linux__) #include <unistd.h> #else #error "Unsupported platform" #endif // Header guard (in header files) #ifndef MY_HEADER_H #define MY_HEADER_H // Header content... #endif
4. Common Predefined Macros
| Macro | Description |
|---|---|
__FILE__ | Current file name (string) |
__LINE__ | Current line number (int) |
__DATE__ | Compilation date |
__TIME__ | Compilation time |
__cplusplus | Defined when compiling C++ |
5. 📝 Practice Questions
Q1: Write a macro to compute the absolute value.c#define ABS(x) ((x) < 0 ? -(x) : (x))Q2: What is the value ofBAD_PRODUCT(3+2, 4+1)if#define BAD_PRODUCT(a,b) a*b?Answer: 3+2*4+1 = 3+8+1 = 12. The correct version#define PRODUCT(a,b) ((a)*(b))gives((3+2)*(4+1)) = 25. Q3: Why are header guards necessary?Answer: Header guards prevent a header file from being included multiple times in the same translation unit. Without them, multiple definitions would cause compilation errors (e.g., duplicate struct definitions, function declarations). Q4: When should you use a function-like macro instead of a function?Answer: Macros are useful when: (1) you need to operate on different types (type-generic), (2) you need access to the caller's context (LINE, FILE), (3) the overhead of function call matters (inline expansion). Modern C prefers inline functions over macros. Q5: Explain the output of:#define STR(x) #x printf("%s", STR(hello));Answer:#xconverts the parameter to a string literal.STR(hello)expands to"hello". Output: hello.
6. 🔗 Cross-References
- Week 7 - File I/O: Preprocessor for debugging output
- BSCS4032 (Compiler Design): Preprocessor as first compilation phase Join Discord PreviousFile I/ONextHome