2008-09-15 27 views
5

मैं एक उदाहरण के रूप int उपयोग कर रहा हूँ, लेकिन इस के बाद एक संकलक अपवाद फेंक नेट 2+: क्यों (1 == शून्य) अब एक कंपाइलर अपवाद फेंक नहीं देता है?

नेट

में कोई मान प्रकार के लिए लागू होता नेट 1: (नेट 2 में

int i = SomeFunctionThatReturnsInt(); 

if(i == null) //compiler exception here 

अब या 3.5) वह अपवाद चला गया है।

मैं जानता हूँ कि ऐसा क्यों है:

int? j = null; //nullable int 

if(i == j) //this shouldn't throw an exception 

समस्या क्योंकि int? व्यर्थ है और int अब int? करने के लिए एक अंतर्निहित डाली गई है। ऊपर वाक्यविन्यास संकलक जादू है। वास्तव में हम कर रहे हैं:

Nullable<int> j = null; //nullable int 

//compiler is smart enough to do this 
if((Nullable<int>) i == j) 

//and not this 
if(i == (int) j) 

तो अब, हम जब हम i == null कर मिलती है:

if((Nullable<int>) i == null) 

यह देखते हुए कि सी # वैसे भी इस गणना क्यों नहीं इसे करने के लिए बहुत चालाक हो सकता है के लिए संकलक तर्क कर रही है null जैसे पूर्ण मूल्यों से निपटने पर ऐसा न करें?

उत्तर

3

मुझे नहीं लगता कि यह एक कंपाइलर समस्या प्रति से है; एक पूर्णांक मान कभी शून्य नहीं होता है, लेकिन उन्हें समीकरण का विचार अमान्य नहीं है; यह एक वैध कार्य है जो हमेशा झूठा लौटाता है। और संकलक जानता है; कोड

bool oneIsNull = 1 == null; 

compiles, लेकिन एक संकलक चेतावनी देता है: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'

तो यदि आप कंपाइलर त्रुटि वापस चाहते हैं, तो प्रोजेक्ट गुणों पर जाएं और इस त्रुटि के लिए 'त्रुटियों के रूप में चेतावनियों के रूप में व्यवहार करें' चालू करें, और आप उन्हें फिर से ब्रेक-ब्रेकिंग समस्याओं के रूप में देखना शुरू कर देंगे।

1

संकलक अभी भी चेतावनी उत्पन्न करता है जब आप गैर-शून्य प्रकार से शून्य तक तुलना करते हैं, जो कि यह होना चाहिए। हो सकता है कि आपका चेतावनी स्तर बहुत कम हो या यह हाल के संस्करणों में बदला गया था (मैंने केवल .NET 3.5 में किया था)।

3

अजीब ... VS2008 के साथ इस संकलन, लक्ष्यीकरण .NET 3.5:

static int F() 
    { 
     return 42; 
    } 

    static void Main(string[] args) 
    { 
     int i = F(); 

     if (i == null) 
     { 
     } 
    } 

मैं एक संकलक

warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?' 

चेतावनी मिल और यह जो संभवतः JIT निम्नलिखित आईएल उत्पन्न करता है ...

L_0001: call int32 ConsoleApplication1.Program::F() 
    L_0006: stloc.0 
    L_0007: ldc.i4.0 
    L_0008: ldc.i4.0 
    L_0009: ceq 
    L_000b: stloc.1 
    L_000c: br.s L_000e 

क्या आप एक कोड स्निपेट पोस्ट कर सकते हैं?

+0

कंपाइलर सही ढंग से स्पॉट करता है कि यह कभी भी सच नहीं है, जैसा कि आपने 1 == 2 किया था। यह जानना काफी समझदार है कि इंट को अंतर्निहित रूप से int में डाला जा सकता है? और वह int? शून्य से तुलना की जा सकती है। मुझे आशा है कि पूरे ब्लॉक को पट्टी करने के लिए ऑप्टिमाइज़र के स्मार्ट पर्याप्त हैं। – Keith

0

चेतावनी नई है (3.5 मुझे लगता है) - त्रुटि वही है जैसे मैंने 1 == 2 किया था, जो कि यह कभी भी सच नहीं होने के लिए पर्याप्त स्मार्ट है।

मुझे संदेह है कि पूर्ण 3.5 ऑप्टिमाइज़ेशन के साथ पूरे कथन को हटा दिया जाएगा, क्योंकि यह कभी भी सही मूल्यांकन के साथ बहुत स्मार्ट नहीं है।

जबकि मैं संकलित करने के लिए 1==2 चाहता हूं (उदाहरण के लिए कुछ और परीक्षण करते समय फ़ंक्शन ब्लॉक को बंद करने के लिए) मुझे 1==null नहीं चाहिए।

0

यह एक संकलन-समय त्रुटि होना चाहिए, क्योंकि प्रकार असंगत हैं (मान प्रकार कभी शून्य नहीं हो सकते हैं)। यह बहुत दुखी है कि यह नहीं है।

+0

पूरा प्रश्न पढ़ें, मैं समझाता हूं कि ऐसा क्यों होता है। सवाल यह है कि इसे एक विशेष मामले के रूप में क्यों नहीं माना जा सकता है। – Keith

+0

जब मैं कहता हूं "चाहिए" मेरा मतलब है कि एक नैतिक अनिवार्य है, न कि मैं संकलक से अपेक्षा करता हूं। आपके द्वारा वर्णित तर्क कम से कम थोड़ा आकर्षक नहीं है; उन्हें इसे एक स्थिर संकलन विफलता बनाना चाहिए। – DrPizza

1

2.0 ढांचे ने शून्य मूल्य प्रकार पेश किया। यद्यपि शाब्दिक स्थिर "1" कभी शून्य नहीं हो सकता है, इसके अंतर्निहित प्रकार (int) को अब एक निरर्थक int प्रकार में डाला जा सकता है। मेरा अनुमान है कि संकलक अब यह नहीं मान सकता कि int प्रकार शून्य नहीं हैं, भले ही यह एक शाब्दिक स्थिर हो। 2.0:

चेतावनी 1 अभिव्यक्ति का परिणाम हमेशा 'झूठा' होता है क्योंकि 'int' प्रकार के मूल्य 'int' के बराबर 'int' के बराबर नहीं होता है, तो मुझे चेतावनी मिलती है।

+0

जैसा मैंने कहा - संकलक जानता है कि int को अंतर्निहित रूप से int में डाला जा सकता है? और int? शून्य से तुलना की जा सकती है। चेतावनी किसी भी वास्तविक तुलना के लिए सामान्य नहीं है। 1 == 2 एक ही चेतावनी फेंक देगा। – Keith

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