Preprocessor (ตัวประมวลผลก่อนคอมไพล์) ทำงานก่อน Compilation จริงๆ จัดการ Directives เริ่มต้นด้วย `#` ไม่ใช่ C++ Statements (ไม่มี Semicolon)
Directives หลัก
1. #include: รวม Header File
#include <iostream> // System Header (Angle Brackets)
#include "my_header.h" // User Header (Quotes)
2. #define: Macro Definition
- Object-like Macro:
#define PI 3.14159 - Function-like Macro:
#define MAX(a,b) ((a)>(b)?(a):(b)) - Token Pasting (##):
#define CONCAT(a,b) a##b - Stringizing (#):
#define STR(x) #x
3. Conditional Compilation
#ifdef DEBUG
std::cerr << "Debug: x = " << x << '\n';
#endif
#ifndef NDEBUG
assert(x > 0);
#endif
#if VERSION >= 2
// Code for Version 2+
#else
// Legacy Code
#endif
// Comment out Block
#if 0
legacy_code();
#endif
4. #error, #warning, #pragma
#error "Unsupported Platform"
#warning "Deprecated API used"
#pragma once // Include Guard (Modern)
#pragma pack(push, 1) // Struct Packing
ตัวอย่างครบ: Debug Macro
#include <iostream>
#define DEBUG 1
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
int main() {
int i = 100, j = 30;
#ifdef DEBUG
std::cerr << "Trace: Inside main\n";
#endif
#if 0
std::cout << "This is disabled\n";
#endif
std::cout << "Min: " << MIN(i, j) << '\n'; // 30
#ifdef DEBUG
std::cerr << "Trace: Exiting main\n";
#endif
}
ผลลัพธ์
Trace: Inside main
Min: 30
Trace: Exiting main
Include Guards vs #pragma once
// Traditional Include Guard
#ifndef MY_HEADER_H
#define MY_HEADER_H
// ... declarations
#endif
// Modern (Supported by all major compilers)
#pragma once
// ... declarations
ข้อเสียของ Macros
- No Type Safety (Text Substitution)
- No Scope (Global Pollution)
- Side Effects:
MAX(i++, j++)→ Increment สองครั้ง - Debugging ยาก (ไม่เห็นใน Symbol Table)
Modern C++ Replacements
| Macro | Modern Alternative |
|---|---|
| Constants | constexpr / const Variables |
| Function-like Macros | inline Functions / constexpr Functions |
| Type Aliases | using / typedef |
| Conditional Compilation | if constexpr (C++17) / Concepts (C++20) |
สรุป
Preprocessor ทรงพลังแต่อันตราย ใช้ #include, #define (Constants), Conditional Compilation ให้เหมาะสม หลีกเลี่ยง Function-like Macros ใช้ `inline/constexpr` Functions แทน C++17 `if constexpr` ลดความต้องการ Preprocessor Conditionals ได้มาก