यदि हमारे पास तीन कार्य (फू, बार और बाज) हैं जो इस तरह से बनाये गए हैं ...
foo(bar(), baz())
क्या सी ++ मानक द्वारा कोई गारंटी है कि बार का मूल्यांकन बाज से पहले किया जाएगा?
यदि हमारे पास तीन कार्य (फू, बार और बाज) हैं जो इस तरह से बनाये गए हैं ...
foo(bar(), baz())
क्या सी ++ मानक द्वारा कोई गारंटी है कि बार का मूल्यांकन बाज से पहले किया जाएगा?
जवाबों:
नहीं, ऐसी कोई गारंटी नहीं है। यह C ++ मानक के अनुसार अनिर्दिष्ट है।
बज़्ने स्ट्रॉस्ट्रुप ने यह भी स्पष्ट रूप से "द सी ++ प्रोग्रामिंग लैंग्वेज" तृतीय संस्करण खंड 6.2.2 में, कुछ कारण के साथ स्पष्ट रूप से कहा है:
अभिव्यक्ति मूल्यांकन आदेश पर प्रतिबंध के अभाव में बेहतर कोड उत्पन्न किया जा सकता है
यद्यपि तकनीकी रूप से यह उसी खंड के पहले भाग को संदर्भित करता है जो कहता है कि किसी अभिव्यक्ति के कुछ हिस्सों के मूल्यांकन का क्रम भी अनिर्दिष्ट है, अर्थात
int x = f(2) + g(3); // unspecified whether f() or g() is called first
बार () और बाज () के लिए कोई निर्दिष्ट आदेश नहीं है - मानक केवल यही कहता है कि वे दोनों का मूल्यांकन फू () से पहले किया जाएगा। C ++ मानक से, खंड 5.2.2 / 8:
तर्कों के मूल्यांकन का क्रम अनिर्दिष्ट है।
bar
, फिर लाइन 1 की baz
, फिर लाइन 2 की bar
, आदि), जो भी अच्छा है। :-)
[5.2.2] फंक्शन कॉल से,
तर्कों के मूल्यांकन का क्रम अनिर्दिष्ट है। फ़ंक्शन में प्रवेश करने से पहले तर्क अभिव्यक्ति मूल्यांकन के सभी दुष्प्रभाव।
इसलिए, इस बात की कोई गारंटी नहीं है कि bar()
पहले चलेगा baz()
, केवल वही bar()
और baz()
पहले कहा जाएगा foo
।
यह भी नोट करें:
को छोड़कर, जहां उल्लेख किया गया [जैसे विशेष नियम
&&
और||
], अलग-अलग संचालकों के संचालन के मूल्यांकन का क्रम और व्यक्तिगत अभिव्यक्तियों के उपप्रकार, और जिस क्रम में दुष्प्रभाव होते हैं, वह अनिर्दिष्ट है।
इसलिए भले ही आप चाहे पूछ रहे थे bar()
पहले चलेंगे baz()
में foo(bar() + baz())
, आदेश अभी भी अनिर्दिष्ट है।
&
, &&
बाएं से दाएं मूल्यांकन की गारंटी देता है: दूसरे ऑपरेंड का मूल्यांकन नहीं किया जाता है यदि पहला ऑपरेंड है false
।"
C ++ 17 ऑपरेटरों के लिए मूल्यांकन आदेश को निर्दिष्ट करता है जो C ++ 17 तक अनिर्दिष्ट था। प्रश्न देखें C ++ 17 द्वारा प्रस्तुत मूल्यांकन आदेश गारंटी क्या हैं? लेकिन अपनी अभिव्यक्ति पर ध्यान दें
foo(bar(), baz())
अभी भी अनिर्दिष्ट मूल्यांकन आदेश है।
C ++ 11 में, संबंधित पाठ 8.3.6 डिफ़ॉल्ट तर्क / 9 (जोर मेरा) में पाया जा सकता है
हर बार फ़ंक्शन को कॉल करने पर डिफ़ॉल्ट तर्कों का मूल्यांकन किया जाता है। फ़ंक्शन तर्कों के मूल्यांकन का क्रम अनिर्दिष्ट है । नतीजतन, एक फ़ंक्शन के मापदंडों का उपयोग डिफ़ॉल्ट तर्क में नहीं किया जाएगा, भले ही उनका मूल्यांकन न किया जाए।
उसी क्रिया का उपयोग C ++ 14 मानक के रूप में भी किया जाता है, और उसी अनुभाग के अंतर्गत पाया जाता है ।
जैसा कि दूसरों ने पहले ही बताया है, मानक इस विशेष परिदृश्य के लिए मूल्यांकन के आदेश पर कोई मार्गदर्शन नहीं देता है। मूल्यांकन का यह क्रम तब संकलक के पास छोड़ दिया जाता है, और संकलक के पास गारंटी हो सकती है।
यह याद रखना महत्वपूर्ण है कि सी ++ मानक वास्तव में असेंबली / मशीन कोड के निर्माण पर संकलक को निर्देश देने के लिए एक भाषा है। मानक समीकरण का केवल एक हिस्सा है। जहां मानक अस्पष्ट है या विशेष रूप से कार्यान्वयन परिभाषित किया गया है, आपको संकलक की ओर मुड़ना चाहिए और यह समझना चाहिए कि यह C ++ निर्देशों को सही मशीन भाषा में कैसे अनुवाद करता है।
इसलिए, यदि मूल्यांकन का क्रम एक आवश्यकता है, या कम से कम महत्वपूर्ण है, और क्रॉस-कंपाइलर संगत होना एक आवश्यकता नहीं है, तो जांच लें कि आपका कंपाइलर आखिरकार इसे एक साथ कैसे जोड़ देगा, आपका जवाब वहां अंतिम झूठ हो सकता है। ध्यान दें कि संकलक भविष्य में इसे कार्यप्रणाली बदल सकता है