c++ - दोहरा मूल्यांकन क्या है और इसे क्यों टाला जाना चाहिए?




macros preprocessor-directive (3)

निम्नलिखित अभिव्यक्ति पर विचार करें:

 x = max(Foo(), Bar());

जहां Foo और Bar इस तरह हैं:

int Foo()
{
    // do some complicated code that takes a long time
    return result;
}

int Bar()
{
   global_var++;
   return global_var;
}

फिर मूल max अभिव्यक्ति की तरह विस्तार किया जाता है:

 Foo() > Bar() ? Foo() : Bar();

या तो मामले में, फू या बार दो बार निष्पादित होने जा रहा है। इस प्रकार अपेक्षित संख्या से ज्यादा समय लेने या कार्यक्रम की स्थिति को बदलते समय से अधिक होता है। मेरे सरल Bar उदाहरण में, यह लगातार समान मूल्य वापस नहीं करता है

इस सवाल का पहले से ही उत्तर दिया गया है:

मैं पढ़ रहा था कि सी ++ में मैक्रोज़ का उपयोग करना

#define max(a,b) (a > b ? a : b)

परिणामस्वरूप 'दोहरा मूल्यांकन' हो सकता है क्या कोई मुझे एक उदाहरण देता है जब एक डबल मूल्यांकन होता है और यह क्यों बुरा है?

पी एस: हैरानी की बात है कि क्लोज़र में एक उदाहरण को छोड़कर इसके लिए googling जब मैं कोई विस्तृत विवरण नहीं मिल सका (जो मुझे नहीं समझ सकता)।


मैक्रो परिभाषा में a और b दो बार होते हैं इसलिए यदि आप इसे तर्कों के साथ उपयोग करते हैं जिनके दुष्प्रभाव होते हैं, तो साइड इफेक्ट्स को दो बार निष्पादित किया जाता है

max(++i, 4);

कॉल से पहले i = 4 अगर 6 लौटाएगा i = 4 चूंकि यह अपेक्षित व्यवहार नहीं है, आपको max तरह max मैक्रो बदलने के लिए इनलाइन फ़ंक्शंस पसंद करना चाहिए।


कल्पना कीजिए आपने यह लिखा है:

#define Max(a,b) (a < b ? b : a)

int x(){ turnLeft();   return 0; }
int y(){ turnRight();  return 1; }

तो इसे इस तरह कहा जाता है:

auto var = Max(x(), y());

क्या आपको पता है कि turnRight() को दो बार निष्पादित किया जाएगा? मैक्रो, Max का विस्तार होगा:

auto var = (x() < y() ? y() : x());

x() < y() मूल्यांकन के बाद, प्रोग्राम तब y() : x() बीच आवश्यक शाखा लेता है y() : x() : हमारे मामले में true , जो y() को दूसरी बार कॉल करता है । इसे कोलिरू पर लाइव देखें

सीधे शब्दों में कहें, अपने फ़ंक्शन-जैसे मैक्रो के तर्क के रूप में एक अभिव्यक्ति को पारित करना, Max संभवतः उस अभिव्यक्ति का दो बार मूल्यांकन करेगा, क्योंकि अभिव्यक्ति को दोहराया जाएगा, जहां कभी मैक्रो पैरामीटर इसे लेता है, मैक्रो की परिभाषा में उपयोग किया जाता है याद रखें, मैक्रोज़ को पूर्वप्रक्रमक द्वारा नियंत्रित किया जाता है

इसलिए, नीचे की पंक्ति है, किसी फ़ंक्शन को परिभाषित करने के लिए मैक्रोज़ का उपयोग नहीं करें (वास्तव में इस मामले में एक अभिव्यक्ति) बस क्योंकि आप इसे सामान्य मानना चाहते हैं, जबकि इसे फ़ंक्शन टेम्पलेट का उपयोग करके प्रभावी ढंग से किया जा सकता है

पीएस: सी ++ में एक std::max टेम्पलेट फ़ंक्शन है।







preprocessor-directive