मैक्रोज़ पाठ के कॉपी / पेस्ट किए गए टुकड़े हैं जो पूर्व-प्रोसेसर वास्तविक कोड में डाल देंगे; मैक्रो के लेखक को उम्मीद है कि प्रतिस्थापन वैध कोड का उत्पादन करेगा।
इसमें सफल होने के लिए तीन अच्छे "टिप्स" हैं:
मैक्रो को वास्तविक कोड की तरह व्यवहार करने में मदद करें
सामान्य कोड आमतौर पर एक अर्ध-उपनिवेश द्वारा समाप्त होता है। क्या यूजर व्यू कोड की जरूरत नहीं है ...
doSomething(1) ;
DO_SOMETHING_ELSE(2) // <== Hey? What's this?
doSomethingElseAgain(3) ;
इसका मतलब है कि उपयोगकर्ता कंपाइलर से यह उम्मीद करता है कि यदि सेमी-कोलोन अनुपस्थित है, तो वह त्रुटि उत्पन्न कर सकता है।
लेकिन वास्तविक वास्तविक अच्छा कारण यह है कि किसी समय, मैक्रो के लेखक को संभवतः मैक्रो को वास्तविक फ़ंक्शन (शायद इनलेट) के साथ बदलने की आवश्यकता होगी। तो मैक्रो को वास्तव में एक जैसा व्यवहार करना चाहिए ।
इसलिए हमें अर्ध-बृहदान्त्र की जरूरत है।
एक वैध कोड का निर्माण करें
जैसा कि jfm3 के उत्तर में दिखाया गया है, कभी-कभी मैक्रो में एक से अधिक निर्देश होते हैं। और अगर मैक्रो का उपयोग एक इफ स्टेटमेंट के अंदर किया जाता है, तो यह समस्याग्रस्त होगा:
if(bIsOk)
MY_MACRO(42) ;
इस मैक्रो का विस्तार इस प्रकार किया जा सकता है:
#define MY_MACRO(x) f(x) ; g(x)
if(bIsOk)
f(42) ; g(42) ; // was MY_MACRO(42) ;
g
फंक्शन का मान की परवाह किए बिना निष्पादित किया जाएगा bIsOk
।
इसका मतलब है कि हमें स्थूल में एक गुंजाइश जोड़ना होगा:
#define MY_MACRO(x) { f(x) ; g(x) ; }
if(bIsOk)
{ f(42) ; g(42) ; } ; // was MY_MACRO(42) ;
एक मान्य कोड 2 का निर्माण करें
यदि मैक्रो कुछ इस तरह है:
#define MY_MACRO(x) int i = x + 1 ; f(i) ;
हमें निम्नलिखित कोड में एक और समस्या हो सकती है:
void doSomething()
{
int i = 25 ;
MY_MACRO(32) ;
}
क्योंकि यह विस्तार होगा:
void doSomething()
{
int i = 25 ;
int i = 32 + 1 ; f(i) ; ; // was MY_MACRO(32) ;
}
यह कोड निश्चित रूप से संकलन नहीं करेगा। तो, फिर से, समाधान एक गुंजाइश का उपयोग कर रहा है:
#define MY_MACRO(x) { int i = x + 1 ; f(i) ; }
void doSomething()
{
int i = 25 ;
{ int i = 32 + 1 ; f(i) ; } ; // was MY_MACRO(32) ;
}
कोड फिर से सही व्यवहार करता है।
अर्ध-कोलन + स्कोप इफेक्ट्स का संयोजन?
एक C / C ++ मुहावरा है जो इस प्रभाव को उत्पन्न करता है: Do / जबकि लूप:
do
{
// code
}
while(false) ;
ऐसा करने से गुंजाइश बन सकती है, इस प्रकार मैक्रो का कोड एनकैप्सुलेट करता है, और अंत में एक अर्ध-बृहदान्त्र की आवश्यकता होती है, इस प्रकार कोड की आवश्यकता होती है।
बोनस?
C ++ कंपाइलर डू / लूप को ऑप्टिमाइज़ करेगा, क्योंकि तथ्य के बाद की स्थिति झूठी है, जिसे संकलन समय पर जाना जाता है। इसका मतलब है कि एक मैक्रो की तरह:
#define MY_MACRO(x) \
do \
{ \
const int i = x + 1 ; \
f(i) ; g(i) ; \
} \
while(false)
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
MY_MACRO(42) ;
// Etc.
}
के रूप में सही ढंग से विस्तार होगा
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
do
{
const int i = 42 + 1 ; // was MY_MACRO(42) ;
f(i) ; g(i) ;
}
while(false) ;
// Etc.
}
और फिर संकलित और अनुकूलित के रूप में दूर है
void doSomething(bool bIsOk)
{
int i = 25 ;
if(bIsOk)
{
f(43) ; g(43) ;
}
// Etc.
}
void
अंत में टाइप की अभिव्यक्ति जोड़ूंगा ... जैसे ((शून्य) 0) ।