2010-09-15 15 views
5

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

हम जानते हैं कि यह बुरा है, और आम तौर पर संकलक हमें यह बताने के लिए एक अच्छा warning प्रिंट करता है ... अच्छी तरह से gcc (3.4.2) चेक को बहुत दूर धक्का नहीं लग रहा है।

std::string get_env_value(std::string const& key); 

std::string const& get_phase() 
{ 
    std::string const& phase = get_env_value("PHASE"); // [1] 
    std::cout << "get_phase - " << phase << '\n'; 
    return phase;          // [2] 
} 

यह एक गड़बड़ बिना संकलित, और अभी तक हम अपरिभाषित व्यवहार का बुरा दायरे में आते हैं।

रेखा [1] ठीक है क्योंकि मानक निर्दिष्ट करता है कि एक कॉन्स संदर्भ के लिए एक परिवर्तनीय बाध्यता का जीवनकाल को संदर्भ संदर्भ के जीवनकाल से मेल खाने के लिए बढ़ाया जाना चाहिए।

लाइन [2] ठीक भी लगती है ...

  • सी ++ विनिर्देशों इस मामले शामिल हैं?
  • क्या किसी को पता है कि यह आमतौर पर निदान किया जाता है? (मैं एक झंडा या कुछ छूट भी सकते हैं ...)

ऐसा नहीं है कि स्थिर विश्लेषण बताने के लिए कि [1] के लिए एक "जीवन एक्सटेंशन" का उपयोग होने में सक्षम होना चाहिए मुझे लगता है, [2] सुरक्षित नहीं है, लेकिन यह हो सकता है बदसूरत तेजी से मुझे लगता है ...

+0

अरे, यह एक बुरा मामला है! –

+1

आखिरकार यह संभव है कि 'get_env_value()' एक चर के संदर्भ को वापस कर रहा है जो दायरे से बाहर नहीं जाता है, उदाहरण के लिए एक वैश्विक, जिस स्थिति में सबकुछ ठीक होना चाहिए। – UncleBens

+0

@UncleBens: यह एक अच्छा बिंदु है – Chubsdad

उत्तर

5

मानक [2] को कवर नहीं करता है। यह एक रैल्यू को एक कॉन्स संदर्भ से बंधने की अनुमति देता है, लेकिन यह आपको एक कॉन्स संदर्भ वापस करने की अनुमति नहीं देता है और इसके साथ-साथ उस रावल्यू का जीवनकाल भी बढ़ाया जाता है जो इसे विस्तारित करने के लिए बाध्य है।

और सही, स्थैतिक विश्लेषण इसे पकड़ सकता है, लेकिन हमेशा के रूप में यह एक व्यापार बंद है। सी ++ संकलन जितना धीमा है उतना धीमा है, इसलिए कंपाइलर लेखकों को आगे के स्थिर विश्लेषण के लाभों का वजन करना पड़ता है जो उन्हें बढ़ते संकलन समय के खिलाफ बेहतर निदान का उत्पादन करने की अनुमति दे सकते हैं।

+0

इस जाल के लिए लिंट स्थापित किया जा सकता है? –

+0

मैं मानता हूं कि संकलन काफी धीमा है, संकलक लापता रिटर्न और स्थानीय चर के संदर्भ में लौटने के बारे में चेतावनी देता है, हालांकि, मुझे किसी भी तरह से उम्मीद थी कि 'चरण' चेतावनी उठाएगा:/ –

2
  1. नहीं, मुझे नहीं लगता कि मानक उल्लेख/इस विशिष्ट मामले को शामिल करता है।

  2. वीएस 2010 संकलन चेतावनियां (/ जेए,/डब्ल्यू 4) देता है।

तो, निश्चित रूप से यह एक निदान योग्य स्थिति प्रतीत होता है।

तो, मैं समारोह से थोड़ा बदलाव इस प्रकार है, बस कई वापसी पथ बनाने के लिए:

std::string const& get_phase() 
{ 
    std::string const& phase = get_env_value("PHASE"); // [1] 
    std::cout << "get_phase - " << phase << '\n'; 

    if(1){ 
     while(1){ 
      return phase; 
     } 
    } 
    return phase;          // [2] 
} 

अब, वी.एस. पहले के रूप में चेतावनी रिपोर्ट नहीं करता।

एक उदाहरण के रूप में, पहली नज़र में, ऐसा लगता है कि संकलक को पहचानने और पकड़ने के लिए यह आसान होना चाहिए कि सभी पथ एक मूल्य वापस न करें। लेकिन कंपाइलर्स (उदा। वीएस) नहीं करते हैं।

int get_phase() 
{ 
    char ch; 
    if(ch){ 
     return 0; 
    } 
    // nothing returned from here. 
} 

तो, मुझे लगता है कि ओपी में कोड शायद ही जटिलताओं उदाहरण सिर्फ ऊपर दिखाए गए, हालांकि मुझे यकीन है कि नहीं कर रहा हूँ के रूप में हालत का निदान करने में है। एकमात्र अच्छी बात यह है कि मानक इस मामले पर स्पष्ट है।

$ 6.6.3/2 - "एक समारोह के अंत की ओर बहने वाली कोई मूल्य नहीं के साथ एक लाभ के समतुल्य है, यह एक मूल्य लौटने समारोह में अपरिभाषित व्यवहार का परिणाम है।"

ओपी में कोड पर वापस आकर, मुझे लगता है कि मानक इस स्थिति को निदान योग्य स्थिति के लिए अनिवार्य नहीं है, और इसलिए कंपिलर कृपया ऐसा करने के लिए स्वतंत्र हैं। यह मूल रूप से समझा जाता है कि लौटा संदर्भ किसी ऑब्जेक्ट को इंगित करता है जो पहले से ही नष्ट हो चुका है। तो इस तरह के किसी ऑब्जेक्ट तक पहुंचने से एक अपरिभाषित व्यवहार होगा

+0

@Chusbad: अधिकांश कंपाइलर बिना किसी वापसी के कार्यों के बारे में चेतावनी देते हैं (कभी-कभी अपमानजनक, लेकिन केवल कोने के मामलों में)। मुझे वास्तव में एक त्रुटि की उम्मीद नहीं थी ... लेकिन एक चेतावनी बहुत अच्छी होगी :) –

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