मेरी समझ यह है कि C ++ 11 में, जब आप किसी फ़ंक्शन से मान द्वारा स्थानीय चर लौटाते हैं, तो संकलक को उस चर को r- मान संदर्भ के रूप में मानने की अनुमति दी जाती है और इसे वापस करने के लिए फ़ंक्शन से बाहर ले जाते हैं (यदि RVO / NRVO इसके बजाय, निश्चित रूप से नहीं होता है)।
मेरा सवाल है, क्या यह मौजूदा कोड को नहीं तोड़ सकता?
निम्नलिखित कोड पर विचार करें:
#include <iostream>
#include <string>
struct bar
{
bar(const std::string& str) : _str(str) {}
bar(const bar&) = delete;
bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";}
void print() {std::cout << _str << std::endl;}
std::string _str;
};
struct foo
{
foo(bar& b) : _b(b) {}
~foo() {_b.print();}
bar& _b;
};
bar foobar()
{
bar b("Hello, World!");
foo f(b);
return std::move(b);
}
int main()
{
foobar();
return EXIT_SUCCESS;
}
मेरे विचार थे कि किसी स्थानीय वस्तु को नष्ट करने वाले के लिए यह संभव होगा कि वह उस वस्तु को संदर्भित करे जो अव्यवस्थित रूप से स्थानांतरित हो, और इसलिए अप्रत्याशित रूप से एक 'खाली' वस्तु को देखें। मैं इस परीक्षण करने के लिए (देखें कोशिश की http://ideone.com/ZURoeT ), लेकिन मैं स्पष्ट बिना 'सही' परिणाम मिला std::move
में foobar()
। मैं अनुमान लगा रहा हूं कि NRVO के कारण था, लेकिन मैंने उस अक्षम करने के लिए कोड को पुनर्व्यवस्थित करने की कोशिश नहीं की।
क्या मैं सही हूं कि यह परिवर्तन (फ़ंक्शन से बाहर जाने के कारण) स्पष्ट रूप से होता है और मौजूदा कोड को तोड़ सकता है?
अद्यतन यहाँ एक उदाहरण है जो दिखाता है कि मैं किस बारे में बात कर रहा हूँ। निम्नलिखित दो लिंक एक ही कोड के लिए हैं। http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
यदि आप आउटपुट को देखते हैं, तो यह अलग है।
इसलिए, मुझे लगता है कि यह प्रश्न अब बन जाता है, क्या मानक के लिए निहित कदम जोड़ते समय इस पर विचार किया गया था, और यह तय किया गया था कि इस ब्रेकिंग परिवर्तन को जोड़ना ठीक था क्योंकि इस तरह का कोड काफी दुर्लभ है? मुझे आश्चर्य भी है कि क्या कोई संकलक इस तरह के मामलों में चेतावनी देगा ...