2015-09-02 13 views
6

ले जाने cppreferenceअपरिभाषित व्यवहार ::

जब तक अन्यथा उल्लिखित की move page से, सभी मानक पुस्तकालय वस्तुओं है से एक वैध लेकिन अनिर्दिष्ट राज्य में रखा जाता है स्थानांतरित कर दिया गया। यही कारण है, इस तरह का असाइनमेंट ऑपरेटर के रूप में पूर्व शर्त के बिना ही काम करता है, सुरक्षित रूप से एक ही पृष्ठ पर, वस्तु पर इस्तेमाल किया जा सकता के बाद यह

तो से ले जाया गया था उदाहरण से, नीचे इस कोड को माना जाता है अपरिभाषित व्यवहार

vector<string> v_string; 
string example = "example"; 
v_string.push_back(move(example)); 
cout << example << endl; 

MSVC जाएगा कंसोल पर उत्पादन कुछ भी नहीं है, लेकिन अगर मैं इस

vector<int> v_int; 
int number = 10; 
v_int.push_back(move(number)); 
cout << number << endl; 

इच्छा उत्पादन कर 10 एक कारण क है y ऐसा होता है? या यह हमेशा अनिर्धारित व्यवहार है?

+4

ऑब्जेक्ट इनवेरिएंट बनाए रखने के लिए मैं "वैध स्थिति" लेता हूं। तो इसे stdout पर स्ट्रीम करने के लिए ठीक होना चाहिए, उदाहरण के लिए, लेकिन आप सुरक्षित रूप से 'उदाहरण [0]' तक नहीं पहुंच पाए। मुझे लगता है कि आपके उदाहरणों में से कोई भी यूबी दिखाता है। – juanchopanza

+9

निर्दिष्ट नहीं! = अपरिभाषित, आप स्ट्रिंग प्रिंट कर सकते हैं लेकिन अंदर क्या है इसके बारे में कोई गारंटी नहीं है। – user657267

+1

ठीक है, मैंने देखा कि सभी कार्यान्वयन पर, एसटीएल कंटेनर और स्ट्रिंग बस स्थानांतरित होने के बाद खाली हो जाते हैं। –

उत्तर

10

निर्दिष्ट नहीं है अनिर्धारित नहीं है।

सी ++ 11 मानक के अनुसार, अनुभाग 17.3.26:

वैध लेकिन अनिर्दिष्ट राज्य एक वस्तु राज्य सिवाय इसके कि उस वस्तु का अपरिवर्तनशीलताओं वस्तु पर मुलाकात की और संचालन कर रहे हैं निर्दिष्ट नहीं है व्यवहार के प्रकार के रूप में

जैसा कि ऑब्जेक्ट एक वैध स्थिति में है, आप इसे आउटपुट में स्ट्रीम कर सकते हैं, क्योंकि स्ट्रीमिंग में कोई अतिरिक्त पूर्व शर्त नहीं है। हालांकि क्या मुद्रित है निर्दिष्ट नहीं है, इसलिए यह कुछ भी प्रिंट नहीं कर सकता है, या प्रिंट कर सकता है कि आपके पिता बुजुर्गों की गंध करते हैं। आप सुरक्षित रूप से क्या नहीं कर सकते हैं back() जैसे अतिरिक्त पूर्व शर्त वाले फ़ंक्शन का उपयोग करें, इसके अतिरिक्त स्ट्रिंग को खाली होने की आवश्यकता होती है। मान्य तार खाली हो सकते हैं।

पुराने मान को शामिल करना अनिर्दिष्ट लेकिन वैध स्थिति के लिए एक पूरी तरह से स्वीकार्य विकल्प है। int जैसे मौलिक प्रकारों के मामले में एक सरल प्रतिलिपि केवल एक चाल करने का सबसे प्रभावी तरीका है।

यह भी ध्यान दिया जाना चाहिए कि intनहीं एक मानक पुस्तकालय वस्तु है, लेकिन एक बुनियादी प्रकार (धारा 3.9.1 में परिभाषित) है। इसलिए आपका उद्धरण लागू नहीं होता है।

+2

संदर्भ के लिए, यहां मानक से परिभाषा दी गई है: "एक ऑब्जेक्ट स्थिति जो निर्दिष्ट नहीं है सिवाय इसके कि ऑब्जेक्ट के इनवेरिएंट मिले हैं और ऑब्जेक्ट पर ऑपरेशन इसके प्रकार के लिए निर्दिष्ट हैं" – Jens

+0

@ जेन्स धन्यवाद, इसी मानक उद्धरण को जोड़ा गया – Joe

3

है कि एक string सूचक है कि वास्तविक पात्रों को इंगित करता चुराने से कुशलतापूर्वक move घ हो सकता है क्योंकि, तो thats compilers करना क्या, string से move घ "खाली" हो जाता है। int कुशलता से move डी नहीं हो सकता है, तो आप बस एक प्रति बनाते हैं। इसलिए पुराना int अभी भी वहां है। लेकिन यह रिकॉर्ड से बाहर है। बस उन वस्तुओं का उपयोग न करें जिन्हें आप move एड से निर्दिष्ट करते हैं और अनिर्दिष्ट व्यवहार पर भरोसा नहीं करते हैं।

+0

मुझे नहीं लगता कि कंपाइलर्स को यादृच्छिक मानों को याद रखने के लिए याद रखने की अनुमति है। 'std :: move' केवल अपने तर्क को एक xvalue में परिवर्तित करता है। यह बिल्कुल तर्क नहीं बदलता है। – MSalters

+0

@MSalters आप सही हैं। – nwp

0

अपरिभाषित व्यवहार अर्थ केवल यह है

व्यवहार जिसके लिए इस अंतर्राष्ट्रीय मानक नहीं आवश्यकताओं लगाता है। अनुमत अपरिभाषित व्यवहार स्थिति ,, एक अनुवाद समाप्त अप्रत्याशित परिणाम के साथ पूरी तरह से अनदेखी को अनुवाद या प्रोग्राम निष्पादन (के साथ या एक नैदानिक ​​संदेश जारी करने के बिना) पर्यावरण का एक दस्तावेज ढंग विशेषता में दौरान व्यवहार कर करने से लेकर या निष्पादन ( डायग्नोस्टिक संदेश जारी करने के साथ)। कई ग़लत प्रोग्राम संरचनाएं अपरिभाषित व्यवहार को व्यक्त नहीं करती हैं; उन्हें निदान की आवश्यकता है।

यदि आप रुचि रखते हैं, तो "What every C programmer should know about undefined behavior" पर एक नज़र डालें। यह वास्तव में एक आंख खोलने वाला है।

आपके मामले में, यह अनिर्धारित व्यवहार लेकिन अनिर्दिष्ट राज्य नहीं है:

के रूप में तालिका 69 में संकेत वर्ग basic_string का एक उद्देश्य निर्माणों: 21.4.2.16 में, सी ++ मानक चाल निर्माता के अर्थ विज्ञान परिभाषित करता है। संग्रहित आवंटक आवंटन से बनाया गया है। दूसरे रूप में, एक निर्दिष्ट स्थिति में str को अनिर्दिष्ट मान के साथ छोड़ दिया जाता है।

"दूसरा रूप" चालक कन्स्ट्रक्टर है, इसलिए स्ट्रिंग एक अनिर्दिष्ट स्थिति में है।

इसका मतलब है कि ऑब्जेक्ट एक ऐसे राज्य में होना चाहिए जहां इनवेरिएंट मिले हैं, लेकिन बाकी कुछ भी निर्दिष्ट नहीं है। एक स्ट्रिंग के लिए, कोई भी सामग्री ठीक रहेगी।

+1

बहुत यकीन है कि यहां कोई अपरिभाषित व्यवहार नहीं चल रहा है, लेकिन लिंक अभी भी पढ़ने योग्य है। – nwp

+1

@nwp मुझे वास्तव में अर्थशास्त्र परिभाषित करने वाले मानक में एक संदर्भ मिला। स्ट्रिंग एक अनिर्दिष्ट स्थिति में है। मैं इसे अपरिभाषित व्यवहार के कुछ मामले के रूप में गिनता हूं, हालांकि यह सामान्य यूबी नहीं है। – Jens

+0

@ जेन्स: नहीं, यह अपरिभाषित व्यवहार का मामला नहीं है, यहां तक ​​कि कुछ मामला भी नहीं। यह नाटकीय लग सकता है, लेकिन भेद महत्वपूर्ण है: ** कोई ** सौम्य अपरिभाषित व्यवहार नहीं है, और किसी भी प्रोग्राम जिसमें अपरिभाषित व्यवहार शामिल है टूट गया है। इसके विपरीत अनिर्दिष्ट स्थिति पूरी तरह से ठीक है, जब तक आप किसी विशिष्ट राज्य पर भरोसा नहीं करते हैं। –

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