युवल और डेविड के उत्तर मूल रूप से सही हैं; उपसंहार:
- एक अनिर्दिष्ट स्थानीय चर का उपयोग एक संभावित बग है, और इसे कम लागत पर कंपाइलर द्वारा पता लगाया जा सकता है।
- एक असंक्रमित क्षेत्र या सरणी तत्व का उपयोग बग की संभावना कम है, और संकलक में स्थिति का पता लगाना कठिन है। इसलिए कंपाइलर खेतों के लिए एक असमान परिवर्तनशील चर के उपयोग का पता लगाने का कोई प्रयास नहीं करता है, और इसके बजाय प्रोग्राम के व्यवहार को निर्धारित करने के लिए डिफ़ॉल्ट मूल्य के आरंभीकरण पर निर्भर करता है।
डेविड के जवाब के लिए एक टिप्पणीकार पूछता है कि स्थैतिक विश्लेषण के माध्यम से अनसाइनड फ़ील्ड के उपयोग का पता लगाना असंभव क्यों है; यह वह बिंदु है जिसका मैं इस उत्तर में विस्तार करना चाहता हूं।
सबसे पहले, किसी भी चर के लिए, स्थानीय या अन्यथा, यह वास्तव में यह निर्धारित करना असंभव है कि एक चर सौंपा या अनसाइन किया गया है या नहीं। विचार करें:
bool x;
if (M()) x = true;
Console.WriteLine(x);
सवाल "एक्स सौंपा गया है?" "क्या M () सही है?" अब, मान लें कि यदि Fermat की अंतिम प्रमेय ग्यारहवें गजिलियन से कम है और अन्यथा झूठी है, तो सही है। यह निर्धारित करने के लिए कि क्या x निश्चित रूप से असाइन किया गया है, संकलक को अनिवार्य रूप से Fermat के अंतिम प्रमेय का प्रमाण प्रस्तुत करना होगा। कंपाइलर वह स्मार्ट नहीं है।
तो क्या संकलक स्थानीय लोगों के लिए बजाय करता औजार एक एल्गोरिथ्म जो है तेजी से , और overestimates जब एक स्थानीय निश्चित रूप से नहीं सौंपा गया है। यही है, इसमें कुछ गलत सकारात्मक हैं, जहां यह कहता है कि "मैं यह साबित नहीं कर सकता कि यह स्थानीय सौंपा गया है" भले ही आप और मैं जानते हैं कि यह है। उदाहरण के लिए:
bool x;
if (N() * 0 == 0) x = true;
Console.WriteLine(x);
मान लीजिए कि एन () एक पूर्णांक लौटाता है। आप और मैं जानते हैं कि N () * 0 0 होगा, लेकिन संकलक को यह पता नहीं है। (नोट: C # 2.0 संकलक को यह पता था , लेकिन मैंने उस अनुकूलन को हटा दिया, क्योंकि विनिर्देश यह नहीं कहता है कि संकलक है।)
सब ठीक है, तो हम अब तक क्या जानते हैं? स्थानीय लोगों के लिए एक सटीक उत्तर प्राप्त करना अव्यावहारिक है, लेकिन हम सस्ते में नॉट-असाइन-नेस को ओवरस्टाइट कर सकते हैं और एक बहुत अच्छा परिणाम प्राप्त कर सकते हैं जो "आपके अस्पष्ट कार्यक्रम को ठीक करता है" के पक्ष में गलतियां करता है। अच्छी बात है। खेतों के लिए एक ही चीज क्यों नहीं? यही है, एक निश्चित असाइनमेंट चेकर बनाओ जो सस्ते में overestimates?
खैर, एक स्थानीय के लिए आरंभिक रूप से कितने तरीके हैं? इसे विधि के पाठ के भीतर सौंपा जा सकता है। इसे विधि के पाठ में एक लंबोदर के भीतर सौंपा जा सकता है; हो सकता है कि लंबोदर को कभी आमंत्रित न किया जाए, इसलिए वे कार्य प्रासंगिक नहीं हैं। या इसे एकांत विधि के लिए "आउट" के रूप में पारित किया जा सकता है, जिस बिंदु पर हम यह मान सकते हैं कि जब यह विधि सामान्य रूप से वापस आती है। वे बहुत स्पष्ट बिंदु हैं जिन पर स्थानीय को सौंपा गया है, और वे उसी तरीके से वहीं हैं जो स्थानीय घोषित किया गया है । स्थानीय लोगों के लिए निश्चित असाइनमेंट निर्धारित करने के लिए केवल स्थानीय विश्लेषण की आवश्यकता होती है । तरीके कम होते हैं - एक विधि में कोड की एक लाख लाइनों से कम - और इसलिए पूरी विधि का विश्लेषण करना बहुत जल्दी है।
अब खेतों का क्या? एक पाठ्यक्रम के निर्माण में फ़ील्ड्स को आरंभ किया जा सकता है। या एक क्षेत्र इनिशियलाइज़र। या निर्माणकर्ता एक आवृत्ति विधि को कॉल कर सकता है जो फ़ील्ड्स को इनिशियलाइज़ करता है। या कंस्ट्रक्टर वर्चुअल तरीके से कॉल कर सकता है जो खेतों को प्रभावित करता है। या कंस्ट्रक्टर किसी अन्य वर्ग में एक विधि को कॉल कर सकता है, जो एक पुस्तकालय में हो सकता है, जो खेतों को आरंभ करता है। स्थैतिक निर्माण में स्थैतिक क्षेत्रों को आरंभ किया जा सकता है। स्थैतिक क्षेत्रों को अन्य स्थिर रचनाकारों द्वारा आरंभ किया जा सकता है ।
अनिवार्य रूप से एक क्षेत्र के लिए इनिशलाइज़र पूरे प्रोग्राम में कहीं भी हो सकता है , जिसमें वर्चुअल तरीके भी शामिल हैं जो उन पुस्तकालयों में घोषित किए जाएंगे जिनमें यह नहीं लिखा गया है :
// Library written by BarCorp
public abstract class Bar
{
// Derived class is responsible for initializing x.
protected int x;
protected abstract void InitializeX();
public void M()
{
InitializeX();
Console.WriteLine(x);
}
}
क्या इस लाइब्रेरी को संकलित करना एक त्रुटि है? यदि हाँ, तो BarCorp बग को कैसे ठीक करना चाहिए? X को एक डिफ़ॉल्ट मान देकर? लेकिन यह है कि संकलक पहले से ही क्या करता है।
मान लीजिए यह पुस्तकालय कानूनी है। अगर फूकोर्प लिखते हैं
public class Foo : Bar
{
protected override void InitializeX() { }
}
क्या वह त्रुटि है? कंपाइलर को यह कैसे पता लगाना चाहिए? एकमात्र तरीका पूरे कार्यक्रम का विश्लेषण करना है जो प्रोग्राम के माध्यम से हर संभव पथ पर हर क्षेत्र के आरंभिक स्थैतिक को ट्रैक करता है , जिसमें ऐसे पथ शामिल हैं जिनमें रनटाइम पर वर्चुअल विधियों का विकल्प शामिल है । यह समस्या मनमाने ढंग से कठिन हो सकती है ; इसमें लाखों नियंत्रण पथों का अनुकरण किया जा सकता है। स्थानीय नियंत्रण प्रवाह का विश्लेषण माइक्रोसेकंड लेता है और विधि के आकार पर निर्भर करता है। वैश्विक नियंत्रण प्रवाह का विश्लेषण करने में घंटे लग सकते हैं क्योंकि यह कार्यक्रम और सभी पुस्तकालयों में हर पद्धति की जटिलता पर निर्भर करता है ।
तो एक सस्ता विश्लेषण क्यों न करें जो पूरे कार्यक्रम का विश्लेषण करने के लिए नहीं है, और बस और भी अधिक गंभीर रूप से overestimates? ठीक है, एक एल्गोरिथ्म का प्रस्ताव करें जो काम करता है जो सही प्रोग्राम लिखने के लिए बहुत कठिन नहीं है जो वास्तव में संकलित करता है, और डिजाइन टीम इस पर विचार कर सकती है। मुझे ऐसे किसी भी एल्गोरिथ्म का पता नहीं है।
अब, टिप्पणीकार का सुझाव है कि "एक निर्माता को सभी क्षेत्रों को इनिशियलाइज़ करना होगा"। यह एक बुरा विचार नहीं है। वास्तव में, यह ऐसा एक बुरा विचार है कि सी # में पहले से ही संरचना के लिए यह सुविधा है । Ctor के सामान्य रूप से वापस आने तक सभी क्षेत्रों को निश्चित रूप से असाइन करने के लिए एक स्ट्रक्चर कंस्ट्रक्टर की आवश्यकता होती है; डिफ़ॉल्ट कंस्ट्रक्टर सभी फ़ील्ड को उनके डिफ़ॉल्ट मानों पर आरंभ करता है।
कक्षाओं के बारे में क्या? वैसे, आप कैसे जानते हैं कि एक निर्माता ने एक क्षेत्र को इनिशियलाइज़ किया है ? Ctor खेतों को शुरू करने के लिए एक आभासी विधि कह सकता है , और अब हम उसी स्थिति में वापस आ गए हैं जैसे हम पहले थे। संरचनाएं व्युत्पन्न वर्ग नहीं हैं; कक्षाएं हो सकती हैं। क्या एक पुस्तकालय में एक अमूर्त वर्ग की आवश्यकता होती है जिसमें एक निर्माणकर्ता होता है जो अपने सभी क्षेत्रों को आरंभ करता है? अमूर्त वर्ग को कैसे पता चलता है कि खेतों को किन मूल्यों के आधार पर आरंभ किया जाना चाहिए?
जॉन का सुझाव है कि खेतों को शुरू करने से पहले एक कॉटर में कॉलिंग विधियों को प्रतिबंधित करें। तो, संक्षेप में, हमारे विकल्प हैं:
- आम, सुरक्षित, अक्सर उपयोग किए जाने वाले प्रोग्रामिंग मुहावरों को अवैध बनाएं।
- एक महंगा पूरे-कार्यक्रम का विश्लेषण करें जो संकलन को घंटों तक ले जाता है ताकि बग की तलाश हो सके।
- डिफ़ॉल्ट मानों के लिए स्वत: प्रारंभ पर निर्भर है।
डिजाइन टीम ने तीसरा विकल्प चुना।