कंपाइलर्स को त्रुटियों और चेतावनियों की रिपोर्ट कैसे करनी चाहिए?


11

मैं निकट भविष्य में एक कंपाइलर लिखने की योजना नहीं बना रहा हूं; फिर भी, मैं कंपाइलर प्रौद्योगिकियों के साथ काफी दिलचस्पी रखता हूं, और इस सामान को बेहतर कैसे बनाया जा सकता है।

संकलित भाषाओं के साथ शुरू होने पर, अधिकांश कंपाइलरों में दो त्रुटि स्तर होते हैं: चेतावनियां और त्रुटियां, सबसे पहले गैर-घातक सामान जिसे आपको ठीक करना चाहिए, और अधिकांश समय यह इंगित करने में त्रुटियां हैं कि मशीन का उत्पादन करना असंभव है- (या बाइट-) इनपुट से कोड।

हालांकि, यह एक बहुत कमजोर परिभाषा है। जावा जैसी कुछ भाषाओं में, @SuppressWarningनिर्देश का उपयोग किए बिना कुछ चेतावनियों से छुटकारा पाना असंभव है । इसके अलावा, जावा कुछ गैर-घातक समस्याओं को त्रुटियों के रूप में मानता है (उदाहरण के लिए, जावा में अनुपलब्ध कोड एक कारण के लिए एक त्रुटि चलाता है जिसे मैं जानना चाहता हूं)।

C # में समान समस्याएं नहीं हैं, लेकिन इसमें कुछ हैं। ऐसा लगता है कि संकलन कई पासों में होता है, और एक पास फेलिंग आगे के पासों को निष्पादित करने से दूर रखेगा। उस वजह से, जब आपका निर्माण विफल हो जाता है तो त्रुटि गणना आपको अक्सर कम करके आंका जाता है। एक रन पर यह कह सकता है कि आपके पास दो त्रुटियां हैं, लेकिन एक बार जब आप उन्हें ठीक करते हैं तो शायद आपको 26 नए मिलेंगे।

सी और सी ++ के लिए खुदाई बस जावा और सी # संकलन निदान की कमजोरियों पर एक बुरा संयोजन दिखाती है (हालांकि यह कहना अधिक सटीक होगा कि जावा और सी # बस आधी समस्याओं के साथ अपने तरीके से चले गए)। कुछ चेतावनियों में वास्तव में त्रुटियां होनी चाहिए (उदाहरण के लिए जब सभी कोड पथ एक मान नहीं लौटाते हैं) और फिर भी वे चेतावनी दे रहे हैं क्योंकि, मुझे लगता है कि जिस समय उन्होंने मानक, संकलक तकनीक लिखी थी वह इस तरह का बनाने के लिए पर्याप्त नहीं था जाँच अनिवार्य है। एक ही नस में, कंपाइलर अक्सर मानक से अधिक के लिए जांच करते हैं, लेकिन फिर भी अतिरिक्त निष्कर्षों के लिए "मानक" चेतावनी त्रुटि स्तर का उपयोग करते हैं। और अक्सर, कंपाइलर उन सभी त्रुटियों की रिपोर्ट नहीं करेंगे, जो उन्हें तुरंत मिल सकती हैं; उन सभी से छुटकारा पाने के लिए कुछ संकलन करना पड़ सकता है। थूक की तरह Cryptic त्रुटियाँ C ++ कंपाइलर का उल्लेख नहीं करना,

अब यह कहते हुए कि कई बिल्ड सिस्टम विफलताओं की रिपोर्ट करने के लिए कॉन्फ़िगर करने योग्य हैं जब कंपाइलर्स चेतावनी का उत्सर्जन करते हैं, तो हमें बस एक अजीब मिश्रण मिलता है: सभी त्रुटियां घातक नहीं हैं, लेकिन कुछ चेतावनी होनी चाहिए; सभी चेतावनियों के हकदार नहीं हैं, लेकिन कुछ उनके अस्तित्व का उल्लेख किए बिना स्पष्ट रूप से दबाए जाते हैं; और कभी-कभी सभी चेतावनी त्रुटियां बन जाती हैं।

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

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

यह मुझे लगता है कि संकलक त्रुटि रिपोर्टिंग के हर एक कार्यान्वयन मैं सोच सकता हूं कि टूट गया है। जो एक वास्तविक शर्म की बात है, क्योंकि सभी अच्छे प्रोग्रामर इस बात पर जोर देते हैं कि त्रुटियों से सही तरीके से निपटना कितना महत्वपूर्ण है और फिर भी ऐसा करने के लिए अपने स्वयं के उपकरण नहीं मिल सकते हैं।

आपको क्या लगता है कि कंपाइलर त्रुटियों की रिपोर्ट करने का सही तरीका होना चाहिए?


-1: "गैर-संकलित भाषाओं में अभी भी गंदे त्रुटि रिपोर्टिंग के अपने हिस्से हैं" विषय और तर्क। वास्तव में अनहेल्दी। यह एक सवाल है या शिकायत है?
S.Lott

2
@ S.Lott मुझे लगता है कि आप यहाँ किनारे पर थोड़े हैं। मुझे लगता है कि मैं संकलित भाषाओं पर बहुत कठिन था, और यह आपको परेशान नहीं करता था।
zneak

@zneak: अन्य कथन तथ्यात्मक होने के करीब हैं और पार्स करने के लिए कठिन हैं। उस बयान को सबसे अधिक व्यक्तिपरक और तर्कपूर्ण दिखाया गया था।
एस.लॉट

1
@ S.Lott क्या मैं गलत कह रहा हूं कि अजगर एक समय में एक त्रुटि दर्शाता है?
zneak

1
@ S.Lott तब चीजें बदल गई होंगी, क्योंकि पिछली बार मैंने कोशिश की थी, किसी भी सिंटैक्स त्रुटि के कारण पायथन को "संकलन" करने की कोशिश करना बंद कर दिया जाएगा और एक नाम त्रुटि एक अपवाद फेंक देगी और बाकी फ़ंक्शन की जांच नहीं करेगी (हालांकि यह छोड़ दिया था) प्रति परीक्षण योग्य इकाई में एक त्रुटि की रिपोर्ट करने के लिए कमरा)। मेरा व्यक्तिपरक और तर्कपूर्ण कथन एक परिचय था जिसे मैं एक तथ्य मानता था, लेकिन अगर यह अब सच नहीं है तो मैं जाऊंगा और अपने प्रश्न को संपादित करूंगा। अब यह कैसे काम करता है?
zneak

जवाबों:


6

आपका प्रश्न वास्तव में ऐसा नहीं लगता है कि हम कंपाइलर त्रुटियों की रिपोर्ट कैसे करते हैं - बल्कि, यह समस्याओं के वर्गीकरण और उनके बारे में क्या करना है।

यदि हम यह मानकर शुरू करते हैं कि फिलहाल, यह चेतावनी / त्रुटि द्विभाजन सही है, तो आइए देखें कि हम उसके शीर्ष पर कितना अच्छा निर्माण कर सकते हैं। कुछ विचार:

  1. चेतावनी के विभिन्न "स्तर"। इसे लागू करने के लिए बहुत सारे कंपाइलर सॉर्ट करते हैं (उदाहरण के लिए जीसीसी में इसके बारे में चेतावनी दी जाएगी कि यह ठीक से कॉन्फ़िगर करने के लिए बहुत सारे स्विच हैं), लेकिन इसके लिए काम की जरूरत है - उदाहरण के लिए, रिपोर्ट करना कि रिपोर्ट की गंभीरता क्या है, और चेतावनी सेट करने की क्षमता। त्रुटियाँ हैं "केवल एक निर्दिष्ट गंभीरता से ऊपर की चेतावनी के लिए।

  2. त्रुटियों और चेतावनियों का साने वर्गीकरण। यदि कोड विनिर्देशन को पूरा नहीं करता है, तो एक त्रुटि रिपोर्ट की जानी चाहिए और इसलिए इसे संकलित नहीं किया जा सकता है। अगम्य कथन, जबकि संभवत: एक कोडिंग त्रुटि, एक चेतावनी होनी चाहिए , एक त्रुटि नहीं - कोड अभी भी "वैध" है, और ऐसे वैध उदाहरण हैं जिनमें कोई अनुपलब्ध कोड (डिबगिंग के लिए त्वरित संशोधन, उदाहरण के लिए) संकलन करना चाहेगा ।

अब मैं उन बातों से असहमत हूँ:

  1. हर समस्या की रिपोर्ट के लिए अतिरिक्त प्रयास करना। यदि कोई त्रुटि है, तो बिल्ड को तोड़ता है। बिल्ड टूट गया है। जब तक उस त्रुटि को ठीक नहीं किया जाता है, तब तक बिल्ड काम नहीं करेगा। इसलिए, कोड के साथ बाकी सब "गलत" की कोशिश करने और पहचानने के लिए "उस पर ले जाने" के बजाय उस त्रुटि को तुरंत रिपोर्ट करना बेहतर है। खासतौर पर तब जब उन चीजों में से बहुत सी चीजें शुरुआती त्रुटि के कारण होती हैं।

  2. एक चेतावनी-कि-ए-ए-एरर का आपका विशिष्ट उदाहरण। हाँ, यह शायद एक प्रोग्रामर की गलती है। नहीं, यह निर्माण को नहीं तोड़ना चाहिए। अगर मुझे पता है कि फ़ंक्शन का इनपुट ऐसा है कि यह हमेशा मान लौटाएगा, तो मुझे उन अतिरिक्त चेक को जोड़ने के बिना बिल्ड को चलाने और कुछ परीक्षण करने में सक्षम होना चाहिए। हां, यह एक चेतावनी होनी चाहिए। और उस पर एक उच्च गंभीरता लानत है। लेकिन यह चेतावनियों-त्रुटियों के साथ संकलन करने तक अपने आप में बिल्ड को तोड़ना नहीं चाहिए।

विचार?


मैं आपसे सहमत हूं, उन बिंदुओं को छोड़कर, जहां हम असहमत हैं (डुह), इसलिए वह मुझसे +1 है। मुझे लगता है कि हर कोड पथ को या तो वापस करना काफी आसान है या फिर अपने प्रोग्राम को वापस कर दें, यह देखते हुए कि यह वास्तव में अपरिभाषित व्यवहार के मामले में कितना बुरा है, पर विचार करें।
1

7

आपके द्वारा लाया गया एक मुद्दा त्रुटियों की अपूर्ण रिपोर्टिंग था - उदाहरण के लिए, 2 त्रुटियों की रिपोर्टिंग, और जब आप उन्हें ठीक करते हैं, तो आपको एक गुच्छा अधिक मिलता है।

यह (मोटे तौर पर) संकलक लेखक की ओर से एक समझौता है। आपके द्वारा की गई त्रुटि के आधार पर, कंपाइलर के लिए यह समझना बहुत आसान है कि आपके पास जो कुछ भी है, उसे गलत तरीके से समझने के लिए शुरू करें , यह उन त्रुटियों की रिपोर्ट करना शुरू कर देता है जिनका वास्तविकता से बहुत कम लेना-देना है। उदाहरण के लिए, एक साधारण टाइपो पर विचार करें, जहां आपके पास itn x;इसके बजाय कुछ ऐसा हो int x;। जब तक आपने कुछ और नहीं किया है, जो itnकुछ का मतलब है, यह एक त्रुटि के रूप में रिपोर्ट किया जा रहा है। यह ठीक है जहां तक ​​यह जाता है, लेकिन अब विचार करें कि आगे क्या होता है - कंपाइलर बहुत सारे कोड को देखता है जो एक चर के रूप में उपयोग करने की कोशिश करता है x। क्या यह A) रुकना चाहिए और आपको ठीक करना चाहिए, या B) error: "x": undeclared identifierउस आदेश के बारे में 2000 या कुछ गलतियां बताईं ? एक और संभावना पर विचार करें:

int main()[

यह एक और बहुत स्पष्ट गलती है तो - स्पष्ट रूप से यह एक होना चाहिए {एक के बजाय [। संकलक आपको उस हिस्से को बहुत आसानी से बता सकता है - लेकिन क्या इसके बाद किसी त्रुटि के लिए रिपोर्ट करना चाहिए जैसे x=1;कि कुछ कहना error: statement only allowed inside a function?

ध्यान दें कि ये भी काफी तुच्छ समस्याएँ हैं - बहुत बुरे लोगों को ढूंढना आसान है (विशेषकर, जैसा कि हम में से अधिकांश जानते हैं, जब आप C ++ टेम्पलेट में आते हैं)। लब्बोलुआब यह है कि कंपाइलर लेखक आम तौर पर गलत त्रुटियों की रिपोर्टिंग (यानी, कुछ त्रुटि होने पर भी, भले ही यह ठीक है) और वास्तविक त्रुटियों की रिपोर्ट करने में विफल होने के बीच समझौता करने की कोशिश कर रहा है। अंगूठे के कुछ नियम हैं, जो किसी भी दिशा में बहुत दूर जाने से रोकने की कोशिश करते हैं, लेकिन उनमें से लगभग कोई भी कहीं भी एकदम सही नहीं है।

एक अन्य समस्या जिसका आपने उल्लेख किया था वह थी जावा और @SupressWarning। यह ऊपर से काफी अलग है - इसे ठीक करने के लिए काफी तुच्छ होगा। एकमात्र कारण यह निश्चित नहीं है कि ऐसा करना जावा के मूल "चरित्र" के साथ फिट नहीं है - अर्थात, उनकी राय में, "यह एक बग नहीं है, यह एक विशेषता है।" हालांकि यह आम तौर पर एक मजाक है, इस मामले में शामिल लोग इतने गुमराह हैं कि वे वास्तव में इसे सच मानते हैं।

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


3
कई अन्य लोगों के कारण शुरुआती त्रुटियों के बारे में आपकी बात के अलावा, यह भी तथ्य है कि बाद में पास को सफलतापूर्वक पूरा करने के लिए पहले के पास की आवश्यकता होती है। उदाहरण के लिए, सी # कंपाइलर चेक में प्रारंभिक पास में से एक यह सुनिश्चित करने के लिए कि इनहेरिटेंस ग्राफ में कोई चक्र नहीं हैं - आपके पास बी से ए विरासत नहीं है जो ए से विरासत में मिला है। यदि आप ले जाने और सूची तैयार करना चाहते हैं। उसके बाद सभी त्रुटियों के बाद, प्रत्येक बाद में पास साइकिल के साथ सामना करने में सक्षम होगा - यह "अच्छा" संकलन पर भी काफी धीमा कर देता है।
आनन।

@Anon। जावा कंपाइलर शुरुआती उत्तीर्ण होने में बहुत बेहतर प्रयास करता है, और मुझे यह काफी धीमा नहीं लगता है। मेरे लिए यह कुछ कष्टप्रद है कि कितनी जल्दी cscदेता है।
zneak

@zneak: जैसा कि जैरी कहते हैं, यह कंपाइलर्स के डेवलपर्स की ओर से एक समझौता है। अच्छी त्रुटि डायग्नोस्टिक्स लिखना वास्तव में एक बहुत ही कठिन समस्या है ( उदाहरण के लिए क्लैग को देखें कि आप वास्तव में इसे कितना दूर ले जा सकते हैं)। सी # संकलक के चरणों और पास की अच्छी चर्चा के लिए यहां देखें
डीन हार्डिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.