2011-06-16 12 views
32

कोड की निम्न पंक्तियां संकलक चेतावनी क्यों नहीं बनाती हैं?पंक्ति में 2 अपवाद फेंकने से एक पहुंच योग्य कोड चेतावनी क्यों नहीं उत्पन्न होती है?

void Main() 
{ 
    throw new Exception(); 
    throw new Exception(); 
} 

जैसा कि मैंने इसे देखा, संकलक आपको सूचित करना चाहिए कि दूसरा फेंक अपवाद नहीं पहुंचा जा सकता है।

+0

(मैं ध्यान दें कि ReSharper दूसरे 'के रूप में नहीं पहुंचा जा सकता throw' के निशान) – AakashM

+3

पेजिंग एरिक Lippert की संकलक अपरिवर्तित हो गया लगता है .. –

+0

@ डैन एरिक लिपर्ट ने इससे पहले कहा है [वह किबो नहीं है (टिप्पणियों में)] (http://stackoverflow.com/questions/2508945/can-anyone-explain-this-strange-behaviour) - उसके माध्यम से उससे संपर्क करें ब्लॉग अगर आप उसे ब्याज के सवाल पर सतर्क करना चाहते हैं। – AakashM

उत्तर

36

यह स्पष्ट रूप से एक कंपाइलर बग है, और इसे सी # 3.0 में पेश किया गया था - ठीक उसी समय जब मैंने पहुंच-योग्यता परीक्षक को काफी प्रतिक्रिया दी थी। यह शायद मेरा बुरा है, क्षमा करें।

बग पूरी तरह से सौम्य है; मूल रूप से, हम सिर्फ चेतावनी संवाददाता में एक मामला भूल गए। हम पहुंच क्षमता की जानकारी सही ढंग से उत्पन्न करते हैं; जैसा कि अन्य ने ध्यान दिया है, हम कोडजन से पहले पहुंचने योग्य कोड को सही ढंग से ट्रिम करते हैं।

बग चेतावनी जनरेटर में एक लापता मामले से ज्यादा कुछ नहीं है। हमारे पास कुछ मुश्किल कोड है जो सुनिश्चित करता है कि जब आप कोड का कुछ बड़ा हिस्सा पहुंचने योग्य नहीं करते हैं तो हम एक अरब चेतावनियों की रिपोर्ट नहीं करते हैं। कंपाइलर में बिना शर्त गेटोस ("गोटो", "ब्रेक", "जारी रखें") पर सशर्त रिपोर्टिंग के लिए कोड है, सशर्त गेटोस ("अगर", "जबकि" और इसी तरह), अंततः प्रयास करें (जिसमें फॉर्म समकक्ष शामिल हैं आखिरकार, लॉक और उपयोग करने की तरह), ब्लॉक, रिटर्न (उपज रिटर्न और नियमित वापसी), स्थानीय घोषणाएं, लेबल किए गए बयान, स्विच और अभिव्यक्ति बयान।

क्या आप उस सूची में "फेंक बयान" देखते हैं? न ही मैं। ऐसा इसलिए है क्योंकि हम इसे भूल गए थे।

असुविधा के लिए क्षमा चाहते हैं। मैं क्यूए को एक नोट भेजूंगा और हम इसके लिए भाषा के भविष्य के संस्करण में एक फिक्स प्राप्त करेंगे।

इसे मेरे ध्यान में लाने के लिए धन्यवाद।

+1

स्पष्टीकरण एरिक के लिए धन्यवाद। हमारे डेवलपर्स में से एक ने आकस्मिक रूप से "कोड की नई अपवाद()" रेखा को डुप्लिकेट करने के बाद ही जिज्ञासा से पूछा, लेकिन परियोजना अभी भी बनाई गई है (चेतावनियों के साथ त्रुटियों के साथ)। – DaveShaw

+0

@ डेवशॉ इस बग के अजीब परिणाम हैं कि मैं अपने नए "उत्तर" में थोड़ा सा विस्तार करता हूं। –

7

यह एक कंपाइलर चेतावनी/त्रुटि दे सकता है लेकिन दुख की बात यह नहीं है। लेकिन यदि आप आईएल कोड देखते हैं तो केवल पहला अपवाद माना जाता है। आप connect.microsoft.com पर लॉग इन कर सकते हैं और इसे उस चीज़ के रूप में उठा सकते हैं जिसे आप देखना चाहते हैं।

अगर आप नीचे दिए

static void Main(string[] args) 
     { 
      Console.Write("Line 1"); 
      throw new Exception(); 
      throw new Exception(); 
      Console.Write("Line 4"); 
     } 

कोड ILDASM आप इस

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  18 (0x12) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldstr  "Line 1" 
    IL_0006: call  void [mscorlib]System.Console::Write(string) 
    IL_000b: nop 
    IL_000c: newobj  instance void [mscorlib]System.Exception::.ctor() 
    IL_0011: throw 
} // end of method Program::Main 

पहले अपवाद वस्तु कुछ भी नहीं किसी और आईएल में बदल जाती है के बाद मिल जाएगा।

3

यह बग (जैसा कि लिपर्ट इसे ऊपर कहते हैं) के कुछ अजीब परिणाम हैं। बेशक इस तरह कोड भी कोई संकलन समय चेतावनी देता है:

static int Main() 
{ 
    return 0; 

    throw new Exception("Can you reach me?"); 
} 

आप रचनात्मक हैं, तो आप अभी भी throw बयान प्रेरित (असंबद्ध) चेतावनी बना सकते हैं।

static int Main() 
{ 
    return 0; 

    throw new Exception(((Func<string>)(() => { if (2 == 2) { return "yellow"; } return "green"; }))()); 
} 

(कोड सिर्फ एक लैम्ब्डा से एक प्रतिनिधि उदाहरण बनाता है और प्रतिनिधि का आह्वान): इस उत्सुक उदाहरण में, कोड एक चेतावनी की वजह से ही "हरी" पहुंच से बाहर है उत्पन्न करता है।

लेकिन इस उदाहरण में आसान है और बदतर लगता है:

static int Main() 
{ 
    int neverAssigned; 

    return 0; 

    throw new Exception(neverAssigned.ToString()); 
} 

यह पिछले कोड नमूने भी कोई चेतावनी के साथ संकलित!neverAssigned "उपयोग" में कोई समस्या नहीं है क्योंकि "उपयोग" पहुंच योग्य नहीं है। लेकिन आपको स्थानीय वैरिएबल के बारे में कोई चेतावनी भी नहीं मिलती है (और कभी भी "वास्तव में" पढ़ा नहीं जाता)। तो दोहराने के लिए, बिल्कुल कोई चेतावनी नहीं, जो बहुत गलत लगता है।

मुझे आश्चर्य है कि यह व्यवहार Visual C# के भविष्य के संस्करणों में बदला जाएगा या नहीं? इसे बदलने से लोगों को चेतावनियां मिलेंगी जो उनके पास पहले नहीं थीं (जो मेरी राय में वे लायक हैं)।

अलावा: यह व्यवहार Roslyn साथ आधारित सी # 6.0 दृश्य स्टूडियो 2015

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