← Back to C++ Course | Chapter 16: Modern C++ | Lesson 9 of 9

C++ में Preprocessor और Macros

Preprocessor एक helper है जो compile होने से पहले आपके code का text बदल देता है, find-and-replace करने वाले एक editor की तरह। Macros वे shortcuts हैं जिन्हें यह आपके लिए expand करता है।
Syntax
cpp
#define NAME value

#define MACRO(param) expression

#ifndef NAME
#define NAME
#endif

Preprocessor क्या है?

Preprocessor एक distinct text-substitution pass है जो actual compilation शुरू होने से पहले चलता है।

यह source file को किसी भी hash symbol (#) से शुरू होने वाली line के लिए scan करता है और उन directives को process करता है -- जैसे #include, जो literally उस point पर किसी दूसरी file का text insert कर देता है -- इससे पहले कि compiler resulting code कभी देखे।

उदाहरण: What is the Preprocessor?

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the macro GREETING (replaced by the preprocessor)
#define GREETING "Hello"

// Program execution starts in main()
int main() {
	// Print to the console with cout
	std::cout << GREETING << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

#define Constants

#define NAME value एक macro बनाता है जिसे preprocessor बाद में file में जहाँ भी NAME appear हो textually value से replace कर देता है।

क्योंकि यह substitution compilation से पहले होता है, compiler macro name कभी देखता भी नहीं -- यह सिर्फ expanded result देखता है।

उदाहरण: #define Constants

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the macro MAX_SCORE (replaced by the preprocessor)
#define MAX_SCORE 100

// Program execution starts in main()
int main() {
	// Print to the console with cout
	std::cout << MAX_SCORE << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Function-like Macros

Macros parameters भी accept कर सकते हैं, इन्हें superficially functions जैसे behave करने देते हुए -- #define SQUARE(x) ((x)*(x))।

लेकिन क्योंकि यह बिना किसी type checking या scoping के pure text substitution है, macros overload नहीं हो सकते, normal tools से debug नहीं हो सकते, या उतने trust नहीं किए जा सकते जितने real functions।

उदाहरण: Function-like Macros

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the macro SQUARE (replaced by the preprocessor)
#define SQUARE(x) ((x) * (x))

// Program execution starts in main()
int main() {
	// Print to the console with cout
	std::cout << SQUARE(5) << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Conditional Directives

#ifdef, #ifndef, और #endif आपको यह इस आधार पर code के पूरे blocks include या exclude करने देते हैं कि एक macro define हुआ है या नहीं, यही वजह है cross-platform code Windows बनाम Linux के लिए अलग implementations compile करता है, या header guards एक header को एक translation unit में दो बार process होने से रोकते हैं।

उदाहरण: Conditional Directives

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the macro DEBUG_MODE (replaced by the preprocessor)
#define DEBUG_MODE

// Program execution starts in main()
int main() {
#ifdef DEBUG_MODE
	// Print to the console with cout
	std::cout << "Debug build" << std::endl;
#else
	// Print to the console with cout
	std::cout << "Release build" << std::endl;
#endif
	// Return 0 to signal that the program finished successfully
	return 0;
}

Macro Parentheses

क्योंकि macro substitution purely textual है, macro के parameters और इसके overall expression दोनों को parenthesize करने में fail होना silently operator precedence तोड़ सकता है -- #define SQUARE(x) x*x SQUARE(a+b) के लिए गलत result compute करता है, intended (a+b)*(a+b) की बजाय a+b*a+b में expand होते हुए।

उदाहरण: Macro Parentheses

cpp
// Include std::cout and std::cin
#include <iostream>

// Define the macro SQUARE_BAD (replaced by the preprocessor)
#define SQUARE_BAD(x) x*x
// Define the macro SQUARE_GOOD (replaced by the preprocessor)
#define SQUARE_GOOD(x) ((x) * (x))

// Program execution starts in main()
int main() {
	// Print to the console with cout
	std::cout << SQUARE_BAD(1 + 2) << std::endl;
	// Print to the console with cout
	std::cout << SQUARE_GOOD(1 + 2) << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. arguments के चारों ओर parentheses के बिना एक function-like macro लिखना, इसलिए SQUARE(a + 1) गलत expression में expand होता है।
  2. एक #define line के अंत में एक semicolon लगाना, जो replacement text का हिस्सा बन जाता है और expressions तोड़ देता है।
  3. MAX(i++, j) जैसी side effects वाली एक expression एक macro को pass करना, जो इसे दो बार evaluate कर सकता है।
चैप्टर सारांश
  • auto, range-based for loops, और nullptr code को simpler और safer बनाते हैं।
  • Move semantics और rvalue references unnecessary copying से बचते हैं।
  • constexpr, structured bindings, C++20 modules, और preprocessor और macros additional modern और low-level tools हैं।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.