c# यह कोड अगम्य क्यों नहीं है?




.net unreachable-code (4)

स्थैतिक विश्लेषण केवल इतना कर सकता है, और यह केवल अनुपलब्ध के रूप में कोड को चिह्नित करेगा यदि यह साबित कर सकता है कि एक मूल्य नहीं बदला जा सकता है। आपके कोड में, Bar अंदर जो होता है वह विधि प्रवाह के दायरे से बाहर है और इसके बारे में सांख्यिकीय रूप से तर्क नहीं किया जा सकता है। क्या होगा यदि Bar का कंस्ट्रक्टर एक थ्रेड लॉन्च करता है जो B के type वापस सेट करता है? कंपाइलर को इसके बारे में पता नहीं चल सकता है, क्योंकि, बार के आंतरिक भाग को विधि से अलग नहीं किया जाता है।

यदि आपका कोड एक स्थानीय चर के मूल्य की जांच कर रहा था, तो संकलक यह जान सकता है कि क्या इसके बदलने का कोई तरीका नहीं है। लेकिन यहां ऐसा नहीं है।

मुझे एक मामला मिला जहां मेरा कुछ कोड है जो मुझे विश्वास नहीं हो रहा है कि उसका पता नहीं चल पाया है। कोई चेतावनी न तो संकलक द्वारा और न ही विज़ुअल स्टूडियो द्वारा जारी की जाती है।

इस कोड पर विचार करें:

enum Foo { A, B, C }
class Bar { public Foo type; }

static class Program
{
    private static void Main()
    {
        var bar = new Bar { type = Foo.A };

        if (bar.type == Foo.B)
        {
            Console.WriteLine("lol");
        }
    }
}

जाहिर है, कार्यक्रम "लोल" का प्रिंट आउट नहीं करेगा, क्योंकि यदि कथन में स्थिति गलत है। मुझे समझ में नहीं आता कि अगम्य कोड के लिए चेतावनी क्यों जारी नहीं की जाती है। मेरी एकमात्र परिकल्पना यह है कि यदि आप एक बहु-थ्रेडेड प्रोग्राम में दौड़ की स्थिति रखते हैं, तो यह संभव हो सकता है। क्या ये सही है?


क्योंकि संकलन के समय ऐसी कोई गारंटी नहीं दी जा सकती है। इस वैकल्पिक बार वर्ग पर विचार करें

class Bar
{
   Random random = new Random();
   Array Foos = Enum.GetValues(typeof(Foo));

    private Foo _type;
    public Foo type
    {
        get { return _type; }
        set
        {
            _type = (Foo)Foos.GetValue(random.Next(3));
        }
    }
}

कृपया ध्यान दें कि "पहुंच योग्य" को कार्य स्तर पर परिभाषित किया गया है। यह उस फ़ंक्शन के बाहर तक पहुंचने की अनुमति नहीं है जिसे परीक्षण किया जा रहा है, भले ही ऐसा करने के लिए सुरक्षित हो।


आपके द्वारा अपेक्षित चेतावनी लागू नहीं की गई है क्योंकि यह उपयोगी चेतावनी नहीं है।

वास्तविक दुनिया के अनुप्रयोगों में, कंपाइलर को अक्सर कोड के साथ सामना करना पड़ता है जो पूरी तरह से साबित हो सकता है कि यह पहुंच से बाहर है, शायद गंजा के रूप में भी कुछ का सामना करना पड़ सकता है

static class Program
{
    private static void Main()
    {
        if (false)
        {
            Console.WriteLine("lol");
        }
    }
}

मेरे पास इस कंप्यूटर पर C # कंपाइलर नहीं है, लेकिन मुझे यकीन है कि इसके लिए आपको कोई चेतावनी नहीं है। ऐसा इसलिए है, क्योंकि जब आप कोड के एक ब्लॉक के आसपास if (false) { ... } डालते हैं, तो आपने उद्देश्य के लिए किया था, शायद किसी प्रयोग के लिए अस्थायी रूप से कुछ अक्षम करने के लिए। आपको इसके बारे में बताना उपयोगी नहीं होगा।

अधिक सामान्य यह है कि यह एक शाब्दिक false नहीं है, यह एक संकलन-समय स्थिर है कि निर्माण प्रणाली कॉन्फ़िगरेशन के आधार पर सही या गलत पर सेट होगी; आप चाहते हैं कि कंपाइलर एक बिल्ड में अगम्य कोड को हटाए, लेकिन दूसरे को नहीं, और आप शिकायतें भी नहीं चाहते हैं।

इससे भी अधिक सामान्य प्रारंभिक अनुकूलन के लिए है जैसे कि इनलाइनिंग और निरंतर प्रसार की खोज करना कि एक सशर्त हमेशा झूठी होती है; मान लीजिए आपको कुछ पसंद है

static class Program
{
    private static void Fizz(int i)
    {
        if (i % 3 == 0) {
            Console.WriteLine("fizz");
        } else {
            Console.WriteLine(i);
        }
    }

    private static void Main()
    {
        Fizz(4);
    }
}

आप स्पष्ट रूप से यह नहीं बताना चाहेंगे कि फ़िज़ के अंदर सशर्त का एक पक्ष () सिर्फ इसलिए अप्राप्य था क्योंकि उसे इस कार्यक्रम में केवल तर्क 4 के साथ बुलाया गया था।


C # विनिर्देश कहता है,

यदि किसी स्टेटमेंट का पहला एंबेडेड स्टेटमेंट रिचेबल है अगर इफैक्ट रिचेबल है और बूलियन एक्सप्रेशन में लगातार वैल्यू असत्य नहीं है।

और, निरंतर भावों के विषय में,

एक स्थिर अभिव्यक्ति शून्य शाब्दिक या निम्न प्रकारों में से एक के साथ एक मान होना चाहिए: sbyte, बाइट, शॉर्ट, ushort, int, uint, long, ulong, char, float, double, दशमलव, बूल, ऑब्जेक्ट, स्ट्रिंग, या कोई भी गणना प्रकार।

निरंतर अभिव्यक्तियों में केवल निम्नलिखित निर्माणों की अनुमति है:

  • साहित्य ( null शाब्दिक सहित)।
  • वर्ग और संरचना प्रकार के कॉन्स्टेबल सदस्यों के संदर्भ।
  • गणन प्रकार के सदस्यों का संदर्भ।
  • कॉन्स्ट पैरामीटर या स्थानीय चर का संदर्भ
  • कोष्ठबद्ध उप-अभिव्यक्तियाँ, जो स्वयं निरंतर अभिव्यक्ति हैं।
  • कास्ट एक्सप्रेशन, बशर्ते टारगेट टाइप ऊपर सूचीबद्ध प्रकारों में से एक हो। जाँच की और अनियंत्रित अभिव्यक्ति
  • डिफ़ॉल्ट मूल्य अभिव्यक्तियाँ
  • पूर्वनिर्धारित + , ; , और ~ अनियारी ऑपरेटर।
  • पूर्वनिर्धारित + , , * , / , % , << , >> , & , |, |, ^ , && ,, || , == , != < , > , <= , और >= बाइनरी ऑपरेटरों, बशर्ते प्रत्येक ऑपरेंड ऊपर सूचीबद्ध प्रकार का हो।
  • ?: सशर्त ऑपरेटर।

सदस्य पहुंच अभिव्यक्तियाँ इस सूची में नहीं हैं, इसलिए बूलियन अभिव्यक्ति स्थिर नहीं है। इस प्रकार यदि ब्लॉक का शरीर पुन: प्राप्य है।





unreachable-code