2011-08-25 8 views
8
string foo() { return "hello"; } 
int main() 
{ 
    //below should be illegal for binding a non-const (lvalue) reference to a rvalue 
    string& tem = foo(); 

    //below should be the correct one as only const reference can be bind to rvalue(most important const) 
    const string& constTem = foo(); 
} 
  1. जीसीसी संकलन त्रुटि देने के लिए अच्छा है: std::string
  2. VS2008 अस्थायी प्रकार से std::string& के गैर-कॉन्स्ट संदर्भ का अमान्य प्रारंभिकता बहुत खराब नहीं है क्योंकि कम से कम यह देता है संकलन चेतावनी: चेतावनी C4239: गैर-मानक विस्तार का उपयोग किया जाता है: 'प्रारंभिक': std::string से std::string & रूपांतरण एक गैर-कॉन्स संदर्भ केवल एक lvalue
  3. से बाध्य हो सकता है यहां समस्याग्रस्त एक - VS2010 (SP1) कॉम्प्लेक्स ठीक है किसी भी त्रुटि या चेतावनी के बिना, क्यों ?? !! मुझे पता है कि VS2010 में rvalue संदर्भ का उपयोग रावल्यू के साथ बाध्य करने के लिए किया जा सकता है लेकिन मैं डेमो कोड में बजाय && का उपयोग नहीं कर रहा हूं, मैं बस गैर-कॉन्स्ट लैल्व संदर्भ का उपयोग कर रहा था!

क्या कोई मुझे वीएस -2010 के व्यवहार की व्याख्या करने में मदद कर सकता है? क्या यह एक बग है? धन्यवादएक वीएस -2010 बग? एक चेतावनी के बिना रैवल्यू के बाध्यकारी गैर-कॉन्स संदर्भ को अनुमति देना?

+1

आपकी चेतावनी सेटिंग्स क्या हैं? शायद यह आपकी कॉन्फ़िगरेशन है जो बदल गई है, न कि उनके कार्यान्वयन? –

+0

मैं थोड़ी देर के लिए वीएस -2008 का उपयोग कर रहा हूं लेकिन हाल ही में स्थापित वीएस -2010 इसलिए वीएस 10 इसे इसकी डिफ़ॉल्ट सेटिंग का उपयोग करना चाहिए ... – Gob00st

+2

तो मुझे डर है कि चेतावनी सीमा बस इतना अधिक नहीं है। '4xxx' रेंज में चेतावनियां सक्रिय करने के लिए' \ W4' का उपयोग करें। –

उत्तर

11

यह वीएस कंपाइलर्स का एक ज्ञात मुद्दा/विशेषता है। उन्होंने हमेशा इसकी अनुमति दी है और एक्सटेंशन को हटाने में कोई धक्का नहीं लग रहा है।

+0

कोई विचार क्यों एमएस ने इस अवैध सी ++ उपयोग को पहली जगह में अनुमति दी? यह विशेष संदर्भ नियम काफी पुराना होना चाहिए (98 या 03 मानक)? – Gob00st

+0

@ Gob00st: यह एक ऐसा एक्सटेंशन है जो मनमानी सी ++ प्रतिबंध को रोकता है। मैं व्यक्तिगत रूप से दिमाग में हूं कि बाध्यकारी को या तो अनुमति या अस्वीकार किया जाना चाहिए और वर्तमान * आधा अनुमत * वास्तव में एक अजीब स्थिति है। अस्वीकार पूरी तरह से बग की पूरी कक्षा को खत्म कर देगा, भले ही यह दर्दनाक होगा, अनुमत पूरी तरह से चश्मे को सीधा करेगा। –

+2

@ Gob00st - एमएस में कुछ पुराना कोड है जो नियमों को ठीक करने से पहले लिखा गया था (और उनके ग्राहकों के पास भी हो सकता है)।उनका मानना ​​है कि नए मानकों की तुलना में पुराने कोड का समर्थन करना अधिक महत्वपूर्ण है। एक्सटेंशन को बंद करना भी संभव है (और इस प्रकार कुछ विंडोज हेडर संकलित करने में असमर्थ)। –

9

संकलक भाषा परिवर्तन अक्षम करने के साथ एक त्रुटि जारी करेगा, और/W4 पर एक चेतावनी जारी करेगा। हालांकि, इस कोड को हटाने से पहले संकलन कोड टूट जाएगा, और माइक्रोसॉफ्ट ऐसा करने में बहुत अनिच्छुक है। यही कारण है कि वे अपने SFINAE समर्थन को ठीक नहीं करेंगे।

+0

शायद यह उल्लेख करने लायक है कि चेतावनी VS2010 में/W3 से/W4 तक ले जाया गया था। – rustyx

-1

इस समस्या का एक बहुत nastier संस्करण है:

तो: क्या b.F() को कॉल के दौरान b.f बिंदु करता है के लिए? उपर्युक्त उदाहरण, वीएस2013 डिफ़ॉल्ट डीबग सेटिंग्स के साथ संकलित, क्रैश किए बिना चलाता है और प्रिंट करता है, लेकिन मुझे संदेह होगा कि किसी भी अधिक जटिल उदाहरण से भ्रष्टाचार ढेर हो जाएगा। यदि ऐसा नहीं होता है और संकलक इसे काम करने के लिए कुछ 'चालाक' कर रहा है, तो मुझे लगता है कि यह वास्तव में क्या कर रहा है यह है:

class Foo { 
    int _val; 
public: 
    Foo(int v) : _val(v) {} 
    void F() { std::cout << _val << std::endl; } 
}; 

class Bar { 
    Foo f; 
public: 
    Bar(Foo&& f) : f(f) {} 
    void F() { f.F(); } 
}; 

int main() { 
    Bar b(Foo(3)); 
    b.F(); 
} 
+0

ध्यान दें कि यह वही समस्या मौजूद है यदि 'f' इसके बजाय एक कॉन्स्ट संदर्भ था, और मानक द्वारा इसकी अनुमति दी जाएगी। –

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