2010-11-22 14 views
7

हां मैंने sequence points पर आलेख पढ़ा। हालांकि मुझे समझ में नहीं आया कि क्यों ++i = 2 अपरिभाषित व्यवहार का आह्वान करेगा? i का अंतिम मान कुछ भी ध्यान दिए बिना 2 होगा, तो अभिव्यक्ति कैसे आती है?फिर भी अनुक्रम बिंदु से संबंधित एक और प्रश्न

कोड स्निपेट

int main() 
{ 
    int i =0; 
    ++i=2; 
    return 0; 
} 

क्षमा करें मेरी अंग्रेजी बहुत अच्छी नहीं है।

उत्तर

9

आप का मानना ​​है कि यह मान आपके द्वारा दावा किया जाएगा, इस प्रकार यूबी अन्य संभावित परिदृश्यों के बीच स्वयं को प्रकट कर सकता है। कार्यक्रम जो आप उम्मीद करते हैं, आउटपुट कर सकता है, कुछ असंबंधित डेटा, क्रैश, दूषित डेटा आउटपुट कर सकता है या अपने सभी पैसे ऑर्डर पिज्जा खर्च कर सकता है। एक बार सी ++ मानक कहता है कि कुछ निर्माण यूबी है तो आपको किसी विशिष्ट व्यवहार की अपेक्षा नहीं करनी चाहिए। देखे गए परिणाम एक कार्यक्रम से दूसरे कार्यक्रम में भिन्न हो सकते हैं।

+0

लेकिन परिणाम 2 से अलग कैसे हो सकता है? मैंने कुछ ऑनलाइन और ऑफलाइन कंपाइलर्स पर जीसीसी, एमएसवीसी ++, इंटेल सी ++ सहित कोशिश की। मैं 2. – AMS

+1

@AMS से कुछ भी नहीं मिला है अलग: क्या होगा यदि कार्यक्रम भी अपने सभी पैसा खर्च या (एक तीसरी पार्टी के अपने सभी पासवर्ड भेजा http://stackoverflow.com/questions/908872/whats-the-worst-example- की-अपरिभाषित-व्यवहार-वास्तव में-संभव/3554343 # 3554343)? – sharptooth

+0

और यह बिल्कुल मजाक नहीं है - मैं आपको वास्तव में लिंक का पालन करने और इसके पीछे जवाब पढ़ने के लिए प्रोत्साहित करता हूं। – sharptooth

0

ठीक उसी लिंक प्रदान कर रहे हैं से:

  • इसके अलावा, पहले मूल्य केवल मूल्य निर्धारित करने के लिए पहुँचा जा जाएगा संग्रहीत करने के लिए।

इसका क्या अर्थ है? इसका मतलब है कि अगर एक वस्तु एक पूर्ण अभिव्यक्ति के भीतर करने के लिए लिखा है, किसी भी और सभी एक ही अभिव्यक्ति के भीतर यह को पहुँचता सीधे गणना मूल्य का लिखे जाने की में शामिल किया जाना चाहिए।

ऑपरेटर = के बाएं हाथ की ओर इधर, i के लिए उपयोग लिखा मूल्य की गणना में शामिल नहीं है।

0

++ i (होना चाहिए) एक रावल्यू, और इसलिए, एक lvalue के रूप में उपयोग नहीं किया जा सकता है, लेकिन (++ i) = 2; ठीक काम करना चाहिए। मुझे विश्वास नहीं है कि यह यूबी है, लेकिन हमेशा की तरह, मैं गलत हो सकता हूं।

+0

हाँ आप गलत हैं। कोष्ठक जोड़ना उस अभिव्यक्ति की पार्सिंग को नहीं बदलता है, उपसर्ग ऑपरेटर ++ एक लाभा देता है। यूबी एक ही अनुक्रम बिंदु में दो बार एक ही अंतराल को लिखने का परिणाम है। –

+0

@ ग्रेग रोजर्स: धन्यवाद! –

11

यह आप पर स्पष्ट लग रहा है, क्योंकि जाहिरi होगा पहलेi+1 सौंपा जा, तो दूसरा मूल्य 2 सौंपा जा।

हालांकि, इन कार्य के दोनों उसी क्रम बिंदु के भीतर हो, इसलिए यह संकलक पर निर्भर है जो frist होता है और जो दूसरी होता है, इसलिए अलग संकलक कार्यान्वयन कोड है कि अलग-अलग परिणाम दे देंगे उत्पन्न कर सकते हैं, इसलिए यह यूबी है करने के लिए ।

+4

हाँप, और संकलक को विभिन्न संकलनों में एक ही प्रोग्राम का उत्पादन करने की आवश्यकता नहीं है। एनी संकलन पर 0 प्रिंट, दूसरे पर डिस्क मिटा देता है। – sharptooth

1

कॉलिंग ++i = 2; कॉलिंग स्वयं में अनिश्चित व्यवहार का आह्वान नहीं करता है; कोई संकलक, यदि यह चाहता है, तो उस कोड तक पहुंचने पर एक बहुत ही परिभाषित कार्रवाई करें। हालांकि सी ++ मानक बताता है कि ऐसा ऑपरेशन अपरिभाषित है, इसलिए एक कंपाइलर कुछ अप्रत्याशित कर सकता है (जैसे सी ड्राइव पर सभी फाइलों को हटाएं या पोप पर एक टेक्स्ट संदेश भेजें) और फिर भी एक अनुपालन कंपाइलर बनें। एकमात्र चीज जो इस यूबी को बनाती है वह यह है कि मानक कहता है कि यह यूबी है।

शायद सबसे महत्वपूर्ण बात यह है कि एक कंपाइलर का एक संस्करण एक ही कंपाइलर के अगले संस्करण से कुछ अलग कर सकता है।

2

अपरिभाषित व्यवहार इसलिए होता है क्योंकि एक संकलक निम्न कोड लागू कर सकते हैं:

++i = 2; 
या तो के रूप में

:

i = 2; 
++i; 

या

++i; 
i = 2; 

यह भाषा में अनिर्दिष्ट है, एक संकलक उपरोक्त में से किसी एक को लागू करने का चयन कर सकते हैं। पहला और दूसरा 2 का उत्पादन करेगा। तो यह अपरिभाषित है।

संबंधित मुद्दे