मैं मूल्यांकन उल्लंघन के आदेश के बारे में पढ़ रहा था , और वे एक उदाहरण देते हैं जो मुझे पहेली करता है।
1) अगर एक स्केलर ऑब्जेक्ट पर एक साइड इफेक्ट, एक ही स्केलर ऑब्जेक्ट पर दूसरे साइड इफेक्ट के सापेक्ष अन-सेक्विन है, तो व्यवहार अपरिभाषित है।
// snip f(i = -1, i = -1); // undefined behavior
इस संदर्भ में, i
एक स्केलर ऑब्जेक्ट है , जिसका स्पष्ट अर्थ है
अंकगणित प्रकार (3.9.1), एन्यूमरेशन प्रकार, पॉइंटर प्रकार, पॉइंटर से सदस्य प्रकार (3.9.2), एसटीडी :: nullptr_t, और इन प्रकारों के सीवी-योग्य संस्करण (3.9.3) सामूहिक रूप से स्केलर प्रकार के होते हैं।
मैं यह नहीं देखता कि उस मामले में बयान कितना अस्पष्ट है। यह मुझे लगता है कि चाहे पहले या दूसरे तर्क का मूल्यांकन पहले किया जाए, i
समाप्त होता है -1
, और दोनों तर्क भी हैं -1
।
कृपया कोई स्पष्ट कर सकता है?
अपडेट करें
मैं वास्तव में सभी चर्चा की सराहना करता हूं। अब तक, मैं @ हार्मिक के उत्तर को बहुत पसंद करता हूं क्योंकि यह इस कथन को परिभाषित करने की गड़बड़ियों और पेचीदगियों को उजागर करता है, इसके बावजूद कि यह पहली नज़र में कितना सीधा दिखता है। @ acheong87 कुछ मुद्दों को इंगित करता है जो संदर्भ का उपयोग करते समय सामने आते हैं, लेकिन मुझे लगता है कि इस प्रश्न के अनपेक्षित साइड इफेक्ट पहलू के लिए ऑर्थोगोनल है।
सारांश
चूँकि इस प्रश्न पर एक टन ध्यान गया, इसलिए मैं मुख्य बिंदुओं / उत्तरों को संक्षेप में प्रस्तुत करूँगा। सबसे पहले, मुझे यह बताने के लिए एक छोटे से विषयांतर की अनुमति दें कि "क्यों" में निकटता से संबंधित अलग-अलग अर्थ हो सकते हैं, जैसे "किस कारण से ", "किस कारण से ", और "किस उद्देश्य से "। मैं "क्यों" के उन अर्थों में से उत्तर को समूहित करूंगा, जिन्हें उन्होंने संबोधित किया था।
किस कारण से
यहाँ पर मुख्य उत्तर पॉल ड्रेपर से आया है , जिसमें मार्टिन जे का योगदान समान है, लेकिन व्यापक उत्तर के रूप में नहीं। पॉल ड्रेपर का जवाब उबल पड़ता है
यह अपरिभाषित व्यवहार है क्योंकि यह परिभाषित नहीं है कि व्यवहार क्या है।
C ++ मानक क्या कहता है, यह समझाने के संदर्भ में उत्तर कुल मिलाकर बहुत अच्छा है। यह यूबी के कुछ संबंधित मामलों को भी संबोधित करता है जैसे f(++i, ++i);
और f(i=1, i=-1);
। संबंधित मामलों के पहले में, यह स्पष्ट नहीं है कि क्या पहला तर्क होना चाहिए i+1
और दूसरा i+2
या इसके विपरीत; दूसरे में, यह स्पष्ट नहीं है i
कि फ़ंक्शन कॉल के बाद 1 या -1 होना चाहिए। ये दोनों मामले यूबी हैं क्योंकि वे निम्नलिखित नियम के तहत आते हैं:
यदि एक स्केलर ऑब्जेक्ट पर एक साइड इफेक्ट एक ही स्केलर ऑब्जेक्ट पर एक और साइड इफेक्ट के सापेक्ष आरोपित नहीं किया जाता है, तो व्यवहार अपरिभाषित है।
इसलिए, f(i=-1, i=-1)
यूबी भी है क्योंकि यह एक ही नियम के तहत आता है, इसके बावजूद प्रोग्रामर का इरादा स्पष्ट (स्पष्ट) और स्पष्ट नहीं है।
पॉल ड्रेपर ने अपने निष्कर्ष में यह भी स्पष्ट किया है कि
क्या यह परिभाषित व्यवहार हो सकता था? हाँ। क्या इसे परिभाषित किया गया था? नहीं।
जो हमें "किस कारण / उद्देश्य के लिए f(i=-1, i=-1)
अपरिभाषित व्यवहार के रूप में छोड़ दिया गया था" के सवाल पर लाता है ?
किस कारण / उद्देश्य से
यद्यपि C ++ मानक में कुछ ओवरसाइट्स (शायद लापरवाह) हैं, कई चूक अच्छी तरह से तर्कपूर्ण हैं और एक विशिष्ट उद्देश्य की पूर्ति करते हैं। हालांकि मुझे पता है कि उद्देश्य अक्सर "संकलक-लेखक की नौकरी को आसान बनाते हैं", या "तेज कोड" है, मुझे मुख्य रूप से यह जानने में दिलचस्पी थी कि क्या यूबी के रूप में एक अच्छा कारण है f(i=-1, i=-1)
।
हार्मिक और सुपरकैट मुख्य उत्तर प्रदान करते हैं जो यूबी के लिए एक कारण प्रदान करते हैं । हार्मिक बताते हैं कि एक अनुकूलन कंपाइलर जो कई मशीन निर्देशों में अस्थिर रूप से परमाणु असाइनमेंट संचालन को तोड़ सकता है, और यह इष्टतम गति के लिए उन निर्देशों को आगे इंटरलेक्ट कर सकता है। यह कुछ बहुत ही आश्चर्यजनक परिणाम दे सकता है: i
अपने परिदृश्य में -2 के रूप में समाप्त होता है! इस प्रकार, हार्मोनिक दर्शाता है कि एक ही मान को एक से अधिक चर पर कैसे असाइन किया जाए तो इसके दुष्प्रभाव हो सकते हैं यदि ऑपरेशन अप्रयुक्त हैं।
सुपरकैट f(i=-1, i=-1)
ऐसा करने के लिए प्राप्त करने की कोशिश करने के नुकसान की एक संबंधित प्रदर्शनी प्रदान करता है जैसा कि ऐसा लगता है कि इसे करना चाहिए। वह बताते हैं कि कुछ आर्किटेक्चर पर, एक ही मेमोरी एड्रेस पर एक साथ कई राइट्स लिखने पर कड़ी पाबंदी है। एक कंपाइलर को इसे पकड़ने में मुश्किल समय हो सकता है अगर हम कुछ तुच्छ से कम काम कर रहे हैं f(i=-1, i=-1)
।
डेविडफ़ भी हार्मोनिक के समान इंटरलेविंग निर्देशों का एक उदाहरण प्रदान करता है।
हालांकि हरिकेस के प्रत्येक, सुपरकैट और डेविफ के उदाहरण कुछ हद तक वंचित हैं, एक साथ लिया गया है, फिर भी वे एक ठोस कारण प्रदान करने के लिए सेवा करते हैं कि f(i=-1, i=-1)
अपरिभाषित व्यवहार क्यों होना चाहिए।
मैंने हार्मिक के उत्तर को स्वीकार किया क्योंकि इसने सभी अर्थों को संबोधित करने का सबसे अच्छा काम किया, भले ही पॉल ड्रेपर के जवाब ने "किस कारण से" भाग को बेहतर तरीके से संबोधित किया।
अन्य जवाब
जॉनबी बताते हैं कि यदि हम ओवरलोड असाइनमेंट ऑपरेटरों (सिर्फ सादे स्केलर के बजाय) पर विचार करते हैं, तो हम मुसीबत में भी दौड़ सकते हैं।
f(i-1, i = -1)
या कुछ इसी तरह का था।
std::nullptr_t
, और इन प्रकारों के सीवी-योग्य संस्करण (3.9.3) को सामूहिक रूप से स्केलर प्रकार कहा जाता है । "