Preprocessor directives — #define, #ifdef, #ifndef, #include guards
5.1.27· Coding › C Programming
WHY preprocessor exist karta hai?
WHY humein yeh chahiye:
- Code/text reuse karo bina dobara type kiye →
#include. - Magic constants ko naam do taaki changes ek jagah ho →
#define. - Alag situations ke liye alag code compile karo (debug vs release, Windows vs Linux) →
#ifdef/#ifndef. - Header ko do baar paste hone se roko → include guards.
Build pipeline:
#define — cheezein name karna text substitution se
HOW yeh kaam karta hai (object-like macro):
#define PI 3.14159
double area = PI * r * r; // becomes: 3.14159 * r * rYeh step kyun? Preprocessor literally text PI ko 3.14159 se swap karta hai compiler run hone se pehle. Jab tak compiler isko dekhta hai, PI ab exist hi nahi karta.
Function-like macro ("arguments" leta hai):
#define SQUARE(x) ((x) * (x))
int y = SQUARE(3 + 1); // becomes: ((3 + 1) * (3 + 1)) = 16#ifdef, #ifndef, #endif — conditional compilation
WHY: kabhi kabhi aap chahte ho code jo sirf debugging ke dauran exist kare, ya sirf ek OS par. Preprocessor poore code chunks ko text ki tarah delete kar sakta hai compiler ke dekhne se pehle.
#define DEBUG
#ifdef DEBUG
printf("x = %d\n", x); // kept, because DEBUG is defined
#endif
#ifndef MAX
#define MAX 100 // define MAX only if nobody defined it yet
#endifYeh step kyun? #ifndef MAX double-definition se bachata hai — MAX tabhi set karo agar yeh already nahi hai.
Include Guards — #ifndef ka killer use
/* file: types.h */
#ifndef TYPES_H /* if the unique tag is NOT defined... */
#define TYPES_H /* ...define it now (so next time we skip) */
struct Point { int x, y; }; /* the real header body */
#endif /* TYPES_H */HOW yeh kaam karta hai, step by step:
- Pehli baar header paste hota hai:
TYPES_Hundefined hai →#ifndeftrue hai → preprocessorTYPES_Hdefine karta hai aur struct rakhta hai. - Doosri baar yeh paste hota hai:
TYPES_Hab defined hai →#ifndeffalse hai → preprocessor sab kuch delete karta hai#endiftak. Struct sirf ek baar aata hai. ✅
Worked examples
Common mistakes (steel-manned)
Flashcards
C compiler se pehle kaun sa stage run hota hai aur # lines process karta hai?
Kya ek #define macro ek typed variable hai?
Macro arguments mein parentheses kyun wrap karte hain, jaise ((x)*(x))?
#ifdef NAME kya karta hai?
NAME currently defined hai; warna delete kar deta hai.#ifdef aur #ifndef mein kya fark hai?
#ifdef = defined hone par compile karo; #ifndef = NOT defined hone par compile karo.Include-guard pattern likho.
#ifndef TAG phir #define TAG phir body phir #endif.Include guards kaunsi problem solve karte hain?
Include guards ka non-standard one-line alternative kya hai?
#pragma once.#define MAX 100; dangerous kyun hai?
; bhi substitute ho jaata hai, arr[MAX] jaisi usage break kar deta hai → arr[100;].#ifndef BUFFER_SIZE / #define BUFFER_SIZE 256 / #endif kya allow karta hai?
-DBUFFER_SIZE override kar sake; warna 256 ka safe default milta hai.Recall Feynman: 12-saal ke bacche ko samjhao
Socho tum ek essay likhte ho lekin chhote stickers jaise "PI" aur "BIG_NUMBER" chhodte ho. Teacher ke padhne se pehle, ek helper aata hai aur har sticker ko woh asli words se replace karta hai jo tumne use bataye the. Helper yeh bhi follow kar sakta hai notes jaise "yeh paragraph sirf tab rakho agar hum test mode mein hain" aur "agar tum yeh page ek baar already chipka chuke ho, dubara mat chipkao." Woh helper preprocessor hai. Yeh bas text copy, replace, aur remove karta hai — yeh essay ko actually samajhta nahi. Helper ke baad, asli teacher (compiler) cleaned-up version padhta hai.
Connections
- Header files and translation units
- const vs #define vs enum
- Compilation pipeline — preprocess, compile, assemble, link
- Macros vs inline functions
- Conditional compilation for cross-platform code
- Build flags -D and the command line