Preprocessor Directives
Preprocessor क्या है?
आपका code compiler तक पहुँचने से पहले preprocessor नाम का program उसे पढ़ता है और # से शुरू होने वाली हर line को follow करता है। वह header files जोड़ता है, macro नामों को उनके text से बदलता है, और जो code blocks आपने बंद किए हैं उन्हें हटा देता है। नतीजा साधारण C++ होता है, जिसे फिर compiler translate करता है।
# से शुरू होते हैं, एक line में होते हैं, और semicolon पर ख़त्म नहीं होते।सभी directives एक नज़र में
| Directive | उद्देश्य |
|---|---|
#include | दूसरी file का content जोड़ना |
#define | Macro define करना (नाम जो text से बदलता है) |
#undef | Macro definition हटाना |
#if, #elif, #else, #endif | Condition के आधार पर code रखना या छोड़ना |
#ifdef, #ifndef | Macro defined हो (या न हो) तभी code रखना |
#error | Message के साथ compilation रोकना |
#pragma | Compiler-specific निर्देश, जैसे #pragma once |
#line | बताए जाने वाले line numbers बदलना (कम इस्तेमाल) |
#include
#include <iostream> // standard header #include "marks.h" // अपना header
< > और " " का अंतर और include guards कैसे काम करते हैं, देखें header files में।
#define: object-like macros
#include <iostream>
#define SCHOOL "Alpine Public School"
#define MAX_STUDENTS 40
int main() {
std::cout << SCHOOL << " allows " << MAX_STUDENTS << " students per class.\n";
return 0;
}Compilation से पहले हर MAX_STUDENTS की जगह 40 लिख दिया जाता है। C++ में constexpr constant आमतौर पर बेहतर है क्योंकि उसका type होता है — देखें constants और literals।
Function-like macros और उनके जाल
#define SQUARE(x) x * x int a = SQUARE(3 + 1); // बनता है 3 + 1 * 3 + 1 -> 7, 16 नहीं!
Parameter और पूरे body को हमेशा brackets में रखें:
#define SQUARE(x) ((x) * (x))
फिर भी SQUARE(i++) में i दो बार बढ़ता है। constexpr function में ऐसी कोई समस्या नहीं:
constexpr int square(int x) { return x * x; }Conditional compilation
#if/#ifdef और #endif के बीच का code तभी compile होता है जब condition true हो। आम इस्तेमाल: debug output जिसे एक जगह से बंद किया जा सके:
#include <iostream>
#define DEBUG 1
int main() {
int total = 0;
for (int m : {78, 85, 69}) {
total += m;
#if DEBUG
std::cout << "[debug] added " << m << ", total = " << total << "\n";
#endif
}
std::cout << "Total: " << total << "\n";
return 0;
}DEBUG को 0 करते ही debug lines compiled program से पूरी तरह गायब हो जाती हैं। Macro command line से भी define कर सकते हैं: g++ -DDEBUG=1 main.cpp।
Platform के हिसाब से अलग code के लिए predefined macros काम आते हैं:
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif#ifndef include guards और #pragma once
#ifndef MARKS_H #define MARKS_H // ... declarations ... #endif
पहली बार header include होने पर MARKS_H defined नहीं होता, इसलिए content इस्तेमाल होता है और MARKS_H define हो जाता है। बाद के हर include में वह छूट जाता है। #pragma once सभी बड़े compilers पर यही काम एक line में करता है।
#undef और #error
#define LIMIT 10 #undef LIMIT // अब LIMIT मौजूद नहीं #if __cplusplus < 201703L #error "This program needs C++17 or newer" #endif
#error से build शुरुआत में ही साफ़ message के साथ रुक जाता है, बाद की उलझी errors की जगह।
Predefined macros
| Macro | Value |
|---|---|
__LINE__ | मौजूदा line number |
__FILE__ | मौजूदा file का नाम |
__DATE__, __TIME__ | Compilation की तारीख़ और समय |
__cplusplus | C++ standard version, जैसे C++17 के लिए 201703L |
std::cout << "Compiled on " << __DATE__ << " (line " << __LINE__ << ")\n";
आम गलतियाँ
#defineमें semicolon लगाना (#define MAX 100;)।- Function-like macros में brackets भूलना।
#endifभूलना, जिससे "unterminated #if" error आती है।- जहाँ
constexpr,inlinefunctions या templates ज़्यादा साफ़ और type-safe हों, वहाँ macros लेना। - Macro नाम और
(के बीच space:#define SQ (x) ((x)*(x))function-like नहीं, object-like macro बनाता है।
DEBUG switch वाला program लिखें जो factorial loop का हर step सिर्फ DEBUG 1 होने पर print करे। फिर file से #define हटाकर एक बार -DDEBUG=0 और एक बार -DDEBUG=1 से compile करें और output की तुलना करें।
सारांश
- Preprocessor compilation से पहले चलता है और
#वाली lines संभालता है। #includefiles जोड़ता है;#definetext-replacement macros बनाता है।#if/#ifdef/#ifndef ... #endifcode रखते या हटाते हैं — debug code, platforms और include guards के लिए।- Directives कभी semicolon पर ख़त्म नहीं होते।
- C++ में macros की जगह
constexprऔरinlinefunctions बेहतर हैं।
संबंधित: header files, inline functions, constants और literals।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
C++ में preprocessor directive क्या है?
# से शुरू होने वाली line है जिसे compilation से पहले process किया जाता है। Preprocessor इन lines से files include करता है, macro नामों को text से बदलता है, और code के blocks रखता या हटाता है। फिर compiler सिर्फ बचे हुए text को देखता है।C++ में macro और function में क्या अंतर है?
constexpr या inline functions लें।Conditional compilation क्या है?
#if, #ifdef, #ifndef, #elif, #else और #endif से compile करने से पहले code रखा या हटाया जाता है। यह include guards, सिर्फ debug वाले code, और Windows/Linux में अलग code के लिए इस्तेमाल होता है।क्या preprocessor directive semicolon पर ख़त्म होता है?
#define MAX 100; लिखने से semicolon replacement text में चला जाता है, इसलिए int a[MAX]; बनता है int a[100;]; और compile नहीं होता।