2011-12-29 20 views
9

के लिए अनिर्धारित संदर्भ यह सबसे आसान उदाहरण है जिसके साथ मैं समस्या उत्पन्न कर सकता हूं।एक स्थिर स्थानीय चर

template<class T> 
struct X 
{ 
    static void foo() 
    { 
     static int z = 0; 
     []{ z = 1; }(); 
    } 
}; 

int main() 
{ 
    X<int>::foo(); 
    return 0; 
} 

मैं MinGW 4.6 और 4.7 के साथ यह कोशिश की है, उबंटू में भी जी ++ 4.6 और उन सभी मुझे लिंक त्रुटि "` z 'को अपरिभाषित संदर्भ "देते हैं। तो अब यह मुझे आश्चर्यचकित करता है कि यह कानूनी भी है। वीसी 10 में इसके साथ कोई समस्या नहीं है।

यह काम करता है यदि एक्स टेम्पलेट के बजाय एक्स सामान्य वर्ग है। साथ ही, मुझे नहीं लगता कि यह लैम्ब्डा से संबंधित है क्योंकि मुझे स्थानीय क्लास के साथ लैम्ब्डा को प्रतिस्थापित करने के बावजूद त्रुटि मिलती है।

+0

सी ++ 11 टैग जोड़ें, शायद यह आपको बेहतर प्रतिक्रिया देगा – marcinj

उत्तर

10

जी ++ निम्नलिखित स्वीकार करता है, लेकिन कुलपति ++ नहीं करता है:

[&z]{ z = 1; }(); 

यहाँ z पर कब्जा कर लिया जा रहा है तो ग्राम ++ एक अपरिभाषित संदर्भ के बारे में शिकायत नहीं है। हालांकि:

5.1.2/10:

एक पर कब्जा-सूची में पहचानकर्ता अयोग्य नाम लुकअप (3.4.1) के लिए सामान्य नियमों का उपयोग कर देखा जाता है

; इस तरह के प्रत्येक लुकअप को स्थानीय वैम्बा अभिव्यक्ति के दायरे तक पहुंचने वाली स्वत: संग्रहण अवधि के साथ एक चर मिलेगा।

zनहीं स्वत: भंडारण है। z इसलिए कब्जा नहीं किया जा सकता है। जी ++ व्यवहार इसलिए गलत है, और वीसी ++ सही है।

अपने कोड में, कि कुलपति ++ स्वीकार करता है और जी ++ नहीं करता है:

[]{ z = 1; }(); 

z कुलपति ++ के रूप में स्थिर भंडारण है, जो एक लैम्ब्डा शरीर में अनुमति दी है द्वारा पहुँचा है। g ++ स्पष्ट रूप से उपरोक्त स्थिर चर के लिए z नाम को हल नहीं करता है और इसलिए अपरिभाषित संदर्भ फेंकता है, जबकि यह नहीं होना चाहिए। ;

tl डॉ यह शायद ग्राम में एक बग ++

संपादित है: It is indeed a bug और 4.7 में तय हो गई है।

+0

नाइस: यह भी समझा सकता है कि टोनीके का काम वास्तव में क्यों काम करता है, हालांकि मुझे यकीन नहीं है कि "ज़ेड के संदर्भ" में स्वचालित संग्रहण होगा या नहीं। 5.2.1/9 को देखकर, कोई भी यह भी नोट करता है कि "पहुंचने का दायरा" आपके नोट को अंतर्निहित संलग्न कार्य पर रोकता है, इस प्रकार "ग्लोबल्स" को छोड़कर (जिसमें स्वचालित संग्रहण अवधि भी नहीं है)।तो ऐसा लगता है कि कैप्चर सूची प्रतिलिपि द्वारा स्थानीय चर को कैप्चर कर सकती है। –

-1

मुझे समझ में नहीं आता कि यह सामान्य कक्षाओं के लिए क्यों काम करता है, न कि टेम्पलेट्स के लिए। लेकिन आप अगर आप संदर्भ द्वारा स्थानीय चर z कब्जा काम करने के लिए अपने उदाहरण प्राप्त कर सकते हैं:

static void foo() 
{ 
    static int z = 0; 
    [&z]{ z = 1; }(); // Note: [&z] 
} 

विकिपीडिया अधिक जानकारी here है।

+0

@cicada नामक किसी ने भी वही उत्तर पोस्ट किया लेकिन फिर उसने इसे हटा दिया (अब आप एक ही उत्तर के साथ यहां हैं), पता नहीं क्यों उसने इसे हटा दिया 0_o –

+0

@ श्री अनीबिस क्योंकि मैं अभी भी यह पता लगाने की कोशिश कर रहा हूं कि क्यों जी ++ वीसी ++ –

+0

से अलग व्यवहार करता है @ सीकाडा दोनों कंपाइलर्स अलग-अलग व्यवहार करने के लिए स्वतंत्र होते हैं जब किसी के पास संभवतः बग होता है और दूसरा नहीं होता है। –

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