📘 Lesson  ·  Lesson 60

Macros & Preprocessor

Macro क्या है? (त्वरित याद)

Macro एक नियम है जो आप #define से बनाते हैं और C preprocessor उसका इस्तेमाल compiler चलने से पहले आपके code में text बदलने के लिए करता है। अगर #include और include guards जैसे preprocessor basics नए हैं, तो पहले preprocessor directives पढ़ें। यह lesson खासकर macros पर केंद्रित है — preprocessor का सबसे शक्तिशाली और सबसे ख़तरनाक हिस्सा।

Object-like macros (constants)

सबसे सरल macros बस किसी fixed value को एक नाम देते हैं। इन्हें object-like macros कहते हैं।

C Language
#include <stdio.h>
#define PI 3.14159
#define GREETING "Hello!"

int main() {
    printf("PI = %f\n", PI);
    printf("%s\n", GREETING);
    return 0;
}
Output:
PI = 3.141590
Hello!

Compile से पहले preprocessor हर PI को 3.14159 और हर GREETING को "Hello!" से बदल देता है।

Function-like macros

Macros arguments भी ले सकते हैं, functions जैसे दिखते हुए — पर ये अब भी सिर्फ़ text replacement हैं।

C Language
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
    printf("Square = %d\n", SQUARE(5));
    printf("Max = %d\n", MAX(10, 20));
    return 0;
}
Output:
Square = 25
Max = 20

Parentheses क्यों ज़रूरी हैं

यह macro का नंबर-एक जाल है। चूँकि macros अंधा text substitution हैं, parentheses न होने पर चुपचाप गलत जवाब मिल सकते हैं।

C Language
#include <stdio.h>
#define BAD(x)  x * x        // बिना parentheses
#define GOOD(x) ((x) * (x))  // सुरक्षित

int main() {
    printf("BAD(2+3)  = %d\n", BAD(2+3));   // 2+3*2+3 = 11
    printf("GOOD(2+3) = %d\n", GOOD(2+3));  // (2+3)*(2+3) = 25
    return 0;
}
Output:
BAD(2+3) = 11
GOOD(2+3) = 25
⚠️ नियम

Function-like macro में हर argument और पूरे body को parentheses में लपेटें। यह एक आदत ज़्यादातर macro bugs रोक देती है।

# और ## operators

दो विशेष operators सिर्फ़ macros के अंदर होते हैं। # argument को string बना देता है; ## दो tokens को जोड़ देता है।

C Language
#include <stdio.h>
#define SHOW(x)   printf(#x " = %d\n", x)   // stringize
#define JOIN(a,b) a ## b                    // token paste

int main() {
    int value = 42;
    SHOW(value);            // छापता है: value = 42

    int JOIN(my, Num) = 7;  // बनता है: int myNum = 7;
    printf("myNum = %d\n", myNum);
    return 0;
}
Output:
value = 42
myNum = 7

ध्यान दें कैसे #x ने text "value" छापा, और JOIN(my, Num) ने identifier myNum बनाया।

Macros बनाम functions

बिंदुMacroFunction
कब चलता हैCompilation से पहले (text)Run time पर
Type checkingनहींहाँ
गतिCall overhead नहींथोड़ा call overhead
Debuggingकठिनआसान
Side-effect सुरक्षाजोखिम भरासुरक्षित

खतरनाक pitfalls

Parentheses के अलावा macros का एक और classic जाल है: एक से ज़्यादा बार इस्तेमाल हुए arguments एक से ज़्यादा बार evaluate हो सकते हैं।

C Language
#include <stdio.h>
#define SQUARE(x) ((x) * (x))

int main() {
    int n = 4;
    printf("%d\n", SQUARE(n++));  // ((n++) * (n++)) बन जाता है -- असुरक्षित!
    return 0;
}
⚠️ Double evaluation

चूँकि SQUARE(n++) ((n++) * (n++)) में expand होता है, n दो बार बढ़ता है और result undefined होता है। Macro को कभी side effect वाले expressions (जैसे n++) न दें। असली function में यह समस्या नहीं होती।

सारांश

  • Macro एक #define text-replacement नियम है जो compilation से पहले संभाला जाता है।
  • Object-like macros constants को नाम देते हैं; function-like macros arguments लेते हैं।
  • हमेशा हर argument और पूरे macro body को parentheses में रखें।
  • # argument को string बनाता है; ## tokens को जोड़ता है।
  • Macros में type checking नहीं होती और arguments दो बार evaluate हो सकते हैं — संदेह हो तो functions पसंद करें।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

C में macro क्या है?
Macro एक नाम है जो #define से बनाया जाता है और preprocessor उसे compilation से पहले एक text टुकड़े से बदल देता है। यह #define PI 3.14 जैसा सरल constant हो सकता है, या arguments लेने वाला function-like macro। Compiler macro नाम कभी नहीं देखता — सिर्फ़ उसका replacement text।
C में macro और function में क्या अंतर है?
Function असली code है जो run time पर अपनी memory और type checking के साथ चलता है। Macro compilation से पहले किया गया शुद्ध text replacement है, बिना type checking और बिना function-call overhead के। Macros छोटे operations के लिए तेज़ हो सकते हैं पर गलती-प्रवण हैं, जबकि functions सुरक्षित और debug करने में आसान हैं।
Function-like macros में इतने parentheses क्यों ज़रूरी हैं?
क्योंकि macro अंधा text substitution है, parentheses न होने पर आसपास के operators इच्छित क्रम बदल देते हैं। जैसे #define SQ(x) x*x में SQ(2+3) बन जाता है 2+3*2+3 = 11, न कि 25। हर argument और पूरे body को parentheses में लपेटना — ((x)*(x)) — इसे रोकता है।
Macros में # और ## operators क्या करते हैं?
# operator macro argument को string बना देता है ("stringize"), तो #x बन जाता है "x"## operator दो tokens को एक में जोड़ देता है ("token pasting"), तो a ## b बन जाता है ab। ये advanced macros में names और debug messages बनाने में इस्तेमाल होते हैं।
क्या C में macros बुरी practice मानी जाती है?
स्वाभाविक रूप से नहीं, पर इन्हें सावधानी से इस्तेमाल करना चाहिए। Constants के लिए अब कई programmers const या enum पसंद करते हैं, और छोटे operations के लिए inline function सुरक्षित है। Macros conditional compilation और कुछ ऐसे कामों के लिए उपयोगी रहते हैं जो functions नहीं कर सकते, पर जटिल macros का ज़्यादा इस्तेमाल code को पढ़ने और debug करने में कठिन बना देता है।
← Back to C Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 लाइव कोड एडिटर

इस पेज के प्रोग्राम यहीं तैयार हैं — चलाएँ, बदलें और सीखें। कुछ भी इंस्टॉल किए बिना।
OneCompiler द्वारा संचालित। कोड एडिटर में अपने आप आ जाता है — Run दबाकर आउटपुट देखें। अगर एडिटर न खुले तो नए टैब में खोलें.