मुझे हमेशा संकलक चेतावनी क्यों सक्षम करनी चाहिए?


302

मैं अक्सर सुनता हूं कि C और C ++ प्रोग्राम्स को कंपाइल करते समय मुझे "हमेशा कंपाइलर वार्निंग को सक्षम करना चाहिए"। यह क्यों आवश्यक है? मैं उसको कैसे करू?

कभी-कभी मैं यह भी सुनता हूं कि मुझे "चेतावनी को त्रुटियों के रूप में मानना ​​चाहिए"। क्या मैं? मैं उसको कैसे करू?

जवाबों:


341

चेतावनी क्यों सक्षम करें?

C और C ++ कंपाइलर डिफ़ॉल्ट रूप से कुछ सामान्य प्रोग्रामर गलतियों की रिपोर्ट करने में कुख्यात हैं , जैसे:

  • किसी वैरिएबल को इनिशियलाइज़ करना भूल जाता है
  • returnएक समारोह से एक मूल्य के लिए भूल जाते हैं
  • में तर्क printfऔर scanfपरिवारों प्रारूप स्ट्रिंग मिलान नहीं
  • एक फ़ंक्शन का उपयोग पहले से घोषित किए बिना किया जाता है (केवल C)

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

चेतावनियाँ कैसे सक्षम करें?

यह आपके कंपाइलर पर निर्भर करता है।

माइक्रोसॉफ्ट C और C ++ compilers समझ में स्विच की तरह है /W1, /W2, /W3, /W4और /Wall। कम से कम प्रयोग करें /W3/W4और /Wallसिस्टम हेडर फ़ाइलों के लिए स्प्यूरियस चेतावनियों का उत्सर्जन कर सकता है, लेकिन यदि आपकी परियोजना इन विकल्पों में से एक के साथ सफाई से संकलन करती है, तो इसके लिए जाएं। ये विकल्प परस्पर अनन्य हैं।

अधिकांश अन्य कंपाइलर जैसे विकल्पों को समझते हैं -Wall, -Wpedanticऔर -Wextra-Wallआवश्यक है और बाकी सभी की सिफारिश की जाती है (ध्यान दें कि, इसके नाम के बावजूद, -Wallकेवल सबसे महत्वपूर्ण चेतावनी को सक्षम करता है, उन सभी को नहीं)। इन विकल्पों को अलग-अलग या सभी एक साथ उपयोग किया जा सकता है।

आपके IDE के पास उपयोगकर्ता इंटरफ़ेस से इन्हें सक्षम करने का एक तरीका हो सकता है।

चेतावनी को त्रुटियों के रूप में क्यों मानें? वे सिर्फ चेतावनी हैं!

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

आप चेतावनियों को चेतावनी के रूप में छोड़ना नहीं चाहते हैं, भले ही वे सभी झूठे अलार्म हों। यह बहुत छोटी परियोजनाओं के लिए ठीक हो सकता है, जहां उत्सर्जित चेतावनियों की कुल संख्या 7. किसी भी चीज से कम हो, और पुराने परिचितों की बाढ़ में खो जाना एक नई चेतावनी के लिए आसान है। अनुमति न दें। बस अपने सभी प्रोजेक्ट को साफ-सुथरा संकलित करने का कारण बनें।

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

चेतावनियों को त्रुटियों के रूप में कैसे मानें?

यह फिर से कंपाइलर स्विच के साथ किया जाता है। /WXMicrosoft के लिए, अधिकांश अन्य उपयोग करते हैं -Werror। दोनों स्थितियों में, यदि कोई चेतावनी उत्पन्न होती है, तो संकलन विफल हो जाएगा।


107
मैंने यह क्यू एंड ए पोस्ट किया है क्योंकि मैं बीमार हूं और लोगों को चेतावनी देने के लिए कहकर थक गया हूं। अब मैं उन्हें केवल यहां इंगित कर सकता हूं (या, यदि मैं विशेष रूप से बुरे मूड में हूं, तो उनके प्रश्न को एक डुबकी के रूप में बंद कर दूंगा)। इस उत्तर को बेहतर बनाने या अपना खुद का स्वागत करने के लिए आपका स्वागत है!
एन। 'सर्वनाम' मी।


9
एकमात्र संशोधक मैं जोड़ूंगा कि कुछ चेतावनियां आपके आवेदन के लिए सहायक नहीं हो सकती हैं। (मैंने चेतावनी दी है कि कंपाइलर ने एक संरचना में तत्वों के बीच पैडिंग के 2 बाइट्स जोड़े हैं। आवेदन प्रोटोटाइपिंग के लिए था, इसलिए थोड़ी बर्बाद हुई स्मृति ने हमें परेशान नहीं किया।) सभी चेतावनियों को त्रुटियों के रूप में मानें और उसके बाद ही चेतावनी को अक्षम करें। आप जानते हैं कि चेतावनी आपकी मदद क्यों नहीं करेगी।
काइल ए

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

15
@ सरल हां, यह मेरे साथ दो बार हुआ। कोई बड़ाई नहीं। यदि आपने एक संकलक का उपयोग करके सॉफ़्टवेयर के एक अनमने टुकड़े का निर्माण करना चुना है , तो इसका परीक्षण कभी नहीं किया गया था, ठीक है, तो आप अपने आप को कुछ मेनटेन करने के लिए बेहतर तरीके से तैयार होंगे।
एन। 'सर्वनाम' मी।

94

सी, प्रसिद्ध रूप से, एचएलएल के रूप में एक निम्न-स्तरीय भाषा है। C ++, हालाँकि यह C की तुलना में काफी उच्च-स्तरीय भाषा हो सकती है, फिर भी इसके कई लक्षण साझा करती है। और उन लक्षणों में से एक यह है कि भाषाओं को प्रोग्रामर द्वारा डिज़ाइन किया गया था, प्रोग्रामर के लिए - और, विशेष रूप से, प्रोग्रामर जो जानते थे कि वे क्या कर रहे थे।

[इस उत्तर के बाकी हिस्सों के लिए मैं सी पर ध्यान केंद्रित करने जा रहा हूं। अधिकांश मैं जो कहूंगा वह सी ++ पर भी लागू होता है, हालांकि शायद उतना दृढ़ता से नहीं। यद्यपि बज़्ने स्ट्रॉस्ट्रुप ने प्रसिद्ध रूप से कहा है, "सी खुद को पैर में गोली मारना आसान बनाता है; सी ++ इसे कठिन बनाता है, लेकिन जब आप इसे करते हैं तो यह आपके पूरे पैर को उड़ा देता है।" ]

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

लेकिन सी और सी ++ में, आश्चर्यजनक रूप से बड़ी संख्या में चीजें हैं जो आप कर सकते हैं कि "बुरे विचार" हैं, लेकिन जो "नियमों के खिलाफ" औपचारिक रूप से नहीं हैं। कभी-कभी वे कुछ बुरे विचार रखते हैं (लेकिन अन्य समय में खराब हो सकते हैं); कभी-कभी वे लगभग हर समय एक बुरा विचार होते हैं। लेकिन परंपरा हमेशा इन चीजों के बारे में चेतावनी देने के लिए नहीं रही है - क्योंकि, फिर से, धारणा यह है कि प्रोग्रामर जानते हैं कि वे क्या कर रहे हैं, वे इन चीजों को एक अच्छे कारण के बिना नहीं कर रहे हैं, वे एक झुंड से नाराज होंगे। अनावश्यक चेतावनी के।

लेकिन निश्चित रूप से सभी प्रोग्रामर वास्तव में नहीं जानते कि वे क्या कर रहे हैं। और, विशेष रूप से, हर सी प्रोग्रामर (कोई फर्क नहीं पड़ता कि कितना अनुभवी) शुरुआत सी प्रोग्रामर होने के एक चरण से गुजरता है। और यहां तक ​​कि अनुभवी सी प्रोग्रामर लापरवाह हो सकते हैं और गलतियां कर सकते हैं।

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

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

(इस तरह की "गलती" का एक उत्कृष्ट उदाहरण परीक्षण है if(a = b) अधिकांश समय, यह एक गलती है, तो सबसे compilers इन दिनों उस बारे में चेतावनी है -।। कुछ भी डिफ़ॉल्ट रूप से लेकिन अगर आप वास्तव में दोनों असाइन करना चाहते थे bकरने के लिए aऔर परीक्षण परिणाम, आप टाइप करके चेतावनी को अक्षम कर सकते हैं if((a = b))।)

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

इसलिए संकलक को चेतावनी के बारे में पूछने के लिए त्रुटियों के रूप में एक छोटी सी चाल है जो आप इस मानव को प्राप्त करने के लिए अपने आप पर खेल सकते हैं।

व्यक्तिगत रूप से, मैं चेतावनी को त्रुटियों के रूप में मानने के लिए आग्रह नहीं कर रहा हूं। (वास्तव में, अगर मैं ईमानदार हूं, तो मैं कह सकता हूं कि मैंने अपने "व्यक्तिगत" प्रोग्रामिंग में वास्तव में उस विकल्प को कभी भी सक्षम नहीं किया है।) लेकिन आप सुनिश्चित कर सकते हैं कि मुझे वह विकल्प काम में सक्षम हो गया है, जहां हमारी शैली मार्गदर्शिका है (जो मैं लिखा) इसका उपयोग अनिवार्य है। और मैं कहूंगा - मुझे संदेह है कि अधिकांश पेशेवर प्रोग्रामर कहेंगे - कि कोई भी दुकान जो चेतावनियों को चेतावनी नहीं मानती है क्योंकि सी गलत व्यवहार कर रही है, आमतौर पर स्वीकृत उद्योग सर्वोत्तम प्रथाओं का पालन नहीं कर रही है।


9
"प्रोग्रामर जो जानते थे कि वे क्या कर रहे थे" - LOL; अगर मैं कभी भी एक को देखा तो "कोई सच्चा स्कॉट्समैन" नहीं रहा। :)
डैनक्रम्ब

3
@ डनक्रंब एलओएल बैक अचा। मुझे पूरा यकीन नहीं है कि मैं नो ट्रू स्कॉट्समैन फॉलिकेसी को समझता हूं , लेकिन मुझे यह पसंद है, इसलिए यह मेरे लिए एक अच्छा व्यायाम होगा। मुझे लगता है कि यहां आवेदन इस तरह है: "कोई सी प्रोग्रामर कभी नहीं लिखेगा if(a = b), इसलिए हमें इसके बारे में चेतावनी देने की आवश्यकता नहीं है।" (तब कोई व्यक्ति 10 जारी किए गए उत्पादों में 10 महत्वपूर्ण कीड़े की एक सूची बनाता है जो इस विशेष त्रुटि के परिणामस्वरूप होते हैं।) "ठीक है, कोई अनुभवी सी प्रोग्रामर कभी भी यह नहीं लिखेगा कि ..."
स्टीव समिट

3
@SteveSummit, लेकिन वास्तव में अनुभवी C प्रोग्रामर लिख सकता है if (returnCodeFromFoo = foo(bar))और इसका मतलब यह हो सकता है कि कोड को एक स्थान पर पकड़ने और परीक्षण करने के लिए (मान लें कि साइड इफेक्ट्स का एकमात्र उद्देश्य fooहै!) तथ्य यह है कि वास्तव में अनुभवी प्रोग्रामर को पता हो सकता है कि यह नहीं है! अच्छा कोडन शैली बिंदु के पास है;)
alephzero

5
बात यह है, सबसे अनुभवी प्रोग्रामर सबसे अधिक सक्षम करते हैं, यदि सभी नहीं, चेतावनी। यदि वे कुछ उपयोग करना चाहते हैं if (returnCodeFromFoo = foo(bar)), तो वे एक टिप्पणी डालते हैं और चेतावनी को बंद कर देते हैं (ताकि जब रखरखाव प्रोग्रामर 4 साल बाद इसे देखता है, तो उसे पता चलेगा कि कोड जानबूझकर है। उसने कहा, मैंने काम किया। किसी ऐसे व्यक्ति के साथ जो (Microsoft C ++ भूमि में) जोर देकर कहता है कि चेतावनियों के साथ / वॉल को त्रुटियों के रूप में जाना जाता है। उह, यह नहीं है (जब तक कि आप बहुत सारे दमन टिप्पणियों में नहीं डालना चाहते हैं)।
Flydog57

3
जैसा कि कोई है जो दैनिक आधार पर कोड नहीं लिखता है, लेकिन जब मैं ऐसा करता हूं तो नंगे धातु (अक्सर अपने स्वयं के डिजाइन के बोर्ड पर) के साथ मुझे चेतावनी मिलती है। आंतरिक रजिस्टरों में मूल्यों को भरते समय (डीएमए डिस्क्रिप्टर स्थान के लिए एक उदाहरण है) सूचक को रूपांतरण के बारे में चेतावनी का मतलब है कि मैं चेतावनी को साफ करने के लिए एक कास्ट करता हूं। यह एक त्रुटि नहीं होगी, लेकिन अगर कोई और (या खुद भी!) कुछ महीनों में उस कोड को उठा ले तो यह भ्रामक हो सकता है। इसके अलावा, मैं अपने सीएडी उपकरणों के आउटपुट के लिए कोई चेतावनी वर्तमान नियम लागू नहीं करता हूं।
पीटर स्मिथ

39

चेतावनियों में कुछ सबसे कुशल C ++ डेवलपर्स की सबसे अच्छी सलाह है जो एक आवेदन में सेंध लगा सकती है। वे चारों ओर रखने लायक हैं।

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

चेतावनियों को बंद करना, या उन्हें अनदेखा करना, अपने से अधिक कुशल लोगों की मुफ्त सलाह को नजरअंदाज करना चुनने जैसा है। हबीरिस में इसका एक पाठ जो या तो समाप्त हो जाता है जब आप सूरज के बहुत करीब उड़ते हैं और आपके पंख पिघल जाते हैं, या स्मृति भ्रष्टाचार त्रुटि होती है। दोनों के बीच, मैं किसी भी दिन आसमान से गिरता हूँ!

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

मेरे कई अनुप्रयोगों पर हम चेतावनी को त्रुटियों के रूप में नहीं मानते हैं। हम ऐसा इसलिए करते हैं क्योंकि इन विशेष अनुप्रयोगों को अलग-अलग उम्र के कई संकलक के साथ कई प्लेटफार्मों पर संकलन करने की आवश्यकता होती है। कभी-कभी हम पाते हैं कि एक तरफ एक चेतावनी को ठीक करना असंभव है, इसके बिना किसी अन्य प्लेटफॉर्म पर चेतावनी में बदलना। इसलिए हम केवल सावधान हैं। हम चेतावनी का सम्मान करते हैं, लेकिन हम उनके लिए पीछे की ओर नहीं झुकते हैं।


11
C ++ का ट्यूरिंग पूरा होने के साथ क्या करना है। बहुत सारी भाषाएँ पूरी तरह से ख़त्म हो रही हैं और अगर आप कुछ गलत करते हैं तो आप पर भरोसा मत करो ....
अलविदा SE

3
@KamiKaze हर भाषा में मुहावरेदार गलतियाँ होंगी (जैसे जावा आपको असंगत equals/ लिखना बंद नहीं कर सकता है hashCode, और यह कार्यान्वयन समस्या का एक गुण है जो रिपोर्ट की गई हैं।
कालपी

2
@KamiKaze ट्यूरिंग पूर्णता बिट यह दिखाने के लिए आती है कि ऐसे मामले हैं जहां कंपाइलर साबित नहीं कर सकते हैं कि आपका कोड योजना के अनुसार काम करने में विफल होगा। यह महत्वपूर्ण है क्योंकि कंपाइलर सभी "गलत" कोड को त्रुटि नहीं बना सकते हैं। त्रुटियों को केवल उन व्यवहारों के लिए आरक्षित किया जा सकता है जो भाषा डिजाइनर निश्चित हैं, हमेशा "गलत" होंगे। (आम तौर पर क्योंकि यह उन रास्तों की ओर जाता है जो असंगत हैं)।
कोरट अमोन

2
जो चुनौती के साथ "सभी चेतावनियों में त्रुटियां हैं।" चेतावनियाँ डिज़ाइन द्वारा, अधिक अवसरवादी होती हैं, जो गलत कोड पर ट्रिगर करने के बदले में कुछ संभावित सही कोड पर ट्रिगर करती हैं। त्रुटियों के रूप में चेतावनी आपको पूर्ण भाषा की क्षमताओं का उपयोग करने में सक्षम नहीं बनाती है।
Cort Ammon

2
हालांकि, सामान्य तौर पर, प्रोग्रामर एक ऐसी भाषा चाहते हैं जो "सुरक्षित" चीज़ से अधिक हो। हम एक ऐसी भाषा चाहते हैं जो वह चीज हो जो हमने सोचा था कि हमने इसे करने के लिए कहा था। इस प्रकार, चेतावनियाँ महत्वपूर्ण हैं क्योंकि जिन चीजों को हम करना चाहते हैं उनका वास्तविक वर्ग एक अर्थपूर्ण वर्ग है। संकलक "गलत" या "असुरक्षित" को परिभाषित करके इसे दूर ले जा सकता है, लेकिन अंत में आपके पास अभी भी उन व्यवहारों का एक सुपरक्लास है जो प्रोग्रामर प्रोग्राम को करना चाहता था। चेतावनियाँ उस सुपरक्लास को कम करने में मदद करती हैं।
Cort Ammon

19

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

सही प्रकार का उपयोग करें, उस मान को लौटाएं, उस वापसी मान का मूल्यांकन करें। समय लें और प्रतिबिंबित करें "क्या यह वास्तव में इस संदर्भ में सही प्रकार है?" "क्या मुझे इसे वापस करने की आवश्यकता है?" और बिग्गी; "क्या यह कोड अगले 10 वर्षों तक पोर्टेबल रहने वाला है?"

पहली जगह में चेतावनी-मुक्त कोड लिखने की आदत डालें।


17

अन्य उत्तर उत्कृष्ट हैं और मैं उनके द्वारा कही गई बातों को दोहराना नहीं चाहता।

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

चेतावनियों पर, और उन्हें ऊर्जावान और आपके चेहरे पर संभव के रूप में होने पर, आपको सचेत करने में मदद करता है कि यदि आप कुछ बदलते हैं तो उस चीज़ के लिए परेशानी होती है जिसे आप नहीं देख सकते।

उदाहरण के लिए लें, ताली की चेतावनी -Wswitch-enum। यदि आप किसी एनम पर स्विच का उपयोग करते हैं और संभावित एनम मानों में से एक को मिस करते हैं, तो यह चेतावनी देता है। यह ऐसा कुछ है जिसे आप सोच सकते हैं कि बनाने के लिए एक अप्रत्याशित गलती होगी: आपने शायद कम से कम Enum मानों की सूची देखी जब आपने स्विच स्टेटमेंट लिखा था। आपके पास एक आईडीई भी हो सकता है जो आपके लिए स्विच विकल्प उत्पन्न करता है, जिससे मानव त्रुटि के लिए कोई जगह नहीं है।

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

आप चेतावनी के बारे में उसी तरह से सोच सकते हैं, जैसे आप स्वचालित परीक्षण मामलों के बारे में सोचेंगे: वे आपको यह सुनिश्चित करने में मदद करते हैं कि कोड समझदार है और ऐसा करने की आवश्यकता है जब आप पहली बार इसे लिखते हैं, लेकिन वे यह सुनिश्चित करने के लिए और भी अधिक मदद करते हैं कि यह सुनिश्चित करें जब आप इसे पसंद करते हैं तो आपको इसकी आवश्यकता होती है। अंतर यह है कि परीक्षण के मामले आपके कोड की आवश्यकताओं के लिए बहुत संकीर्ण रूप से काम करते हैं और आपको उन्हें लिखना होगा, जबकि चेतावनियाँ लगभग सभी कोड के लिए समझदार मानकों पर काम करती हैं, और वे बहुत उदारता से बोफ़िन द्वारा आपूर्ति की जाती हैं जो कंपाइलर बनाते हैं।


9
दूसरी तरह वे रखरखाव में मदद करते हैं, जब आप किसी और के कोड को देख रहे हैं और यह नहीं बता सकते हैं कि क्या साइड-इफेक्ट जानबूझकर था। चेतावनी के साथ, आप जानते हैं कि वे इस मुद्दे से कम से कम वाकिफ थे।
रॉबिन बेनेट

या मेरे मामले में, आप एक एम्बेडेड सिस्टम से एक फ़ाइल आयात करते हैं जिसमें कई हजार मानों वाले एक एनम पर 3000+ लाइन स्विच स्टेटमेंट होता है। "गिरता है" चेतावनियों (गोटो का उपयोग करने से बचा जाता है) ने "संभाला नहीं" कीड़े की एक संख्या का मुखौटा लगाया ... एम्बेडेड संकलक उन दोनों में से किसी का भी उत्सर्जन नहीं करता था, लेकिन बग महत्वपूर्ण थे।
मोद

15

गैर-स्थिर चेतावनियाँ , जल्दी या बाद में, आपके कोड में त्रुटियों को जन्म देंगी


उदाहरण के लिए, एक विभाजन दोष को डीबग करना, प्रोग्रामर को गलती के मूल (कारण) का पता लगाने की आवश्यकता होती है, जो आमतौर पर आपके कोड में एक पूर्व स्थान पर स्थित लाइन की तुलना में होता है जो अंततः विभाजन गलती का कारण बनता है।

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

चेतावनी तय करने से समस्या ठीक होती है .. एक क्लासिक!

उपरोक्त का एक प्रदर्शन .. निम्नलिखित कोड पर विचार करें:

#include <stdio.h>

int main(void) {
  char* str = "Hello world!";
  int idx;

  // Colossal amount of code here, irrelevant to 'idx'

  printf("%c\n", str[idx]);

  return 0;
}

जिसे "वीक्स्ट्रा" ध्वज के साथ संकलित किया गया, जिसे जीसीसी को दिया गया, देता है:

main.c: In function 'main':
main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
    9 |   printf("%c\n", str[idx]);
      |                     ^

जिसे मैं वैसे भी कोड को अनदेखा कर सकता हूं और क्रियान्वित कर सकता हूं .. और फिर मैं एक "भव्य" विभाजन दोष देखूंगा, जैसा कि मेरे आईपी एपिक्यूरस प्रोफेसर कहते थे:

विभाजन दोष

वास्तविक दुनिया के परिदृश्य में इसे डिबग करने के लिए, एक उस पंक्ति से शुरू होगा जो विभाजन की गलती का कारण बनता है और यह पता लगाने का प्रयास करता है कि कारण की जड़ क्या है .. उन्हें उस कॉलॉज़ल राशि के अंदर iऔर strअंदर क्या हुआ है, इसकी खोज करनी होगी। वहाँ पर कोड की ...

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

अगर केवल उन्होंने चेतावनी को नजरअंदाज नहीं किया होता, तो वे तुरंत बग ढूंढ लेते!


4
अपने शीर्षक के लिए: जरूरी नहीं। उदाहरण के लिए, एक सूत्र में कोष्ठक का उपयोग करने के लिए एक चेतावनी जो वास्तव में उन्हें एक गैर-समस्या की ओर इशारा करती है, जो कभी भी त्रुटि का कारण नहीं होगी। किसी दिए गए प्रोग्रामिंग भाषा में ऑपरेटर की प्रक्रियाएँ नहीं बदलती हैं। कभी।
मार्क वैन लीउवेन

4
@MarcvanLeeuwen आप जिस उदाहरण को उद्धृत करते हैं, वह त्रुटि tho में बदल सकता है , उदाहरण के लिए यदि प्रोग्रामर जो ऑपरेटर की प्रक्रिया को याद नहीं रखता है, वह सूत्र को थोड़ा संशोधित करता है। चेतावनी आपको बताती है: "यह किसी के लिए अस्पष्ट हो सकता है, इसे और अधिक स्पष्ट करने के लिए कुछ कोष्ठक जोड़ें"। यद्यपि किसी को इस बात से सहमत होना चाहिए कि मूल पद का शीर्षक हमेशा सत्य नहीं होता है।
ह्यूबर्ट जसनेकी

^ कुछ भी त्रुटि में बदल सकता है। यह आंशिक रूप से कोष्ठक कोड में बग को पूरी तरह से कोष्ठक कोड में प्रस्तुत करना आसान है।
जिम बाल्टर

... एक तरफ के रूप में, मैं डिबगर के लिए सवाल करता हूं, जिसकी पहली प्रतिक्रिया "ओह, यह सेगफॉल्ट str[idx]" से "ठीक नहीं है, कहां हैं strऔर idxपरिभाषित?"
जस्टिन टाइम - मोनिका

2
यदि आप एक विभाजन दोष प्राप्त करते हैं तो आप भाग्यशाली हैं। यदि आप कम भाग्यशाली हैं, तो आप संयोगवश idxऐसा हो सकता है कि आपके परीक्षण पर अपेक्षित मूल्य हो (अपेक्षित मूल्य 0 होने पर भी बहुत कम होने की संभावना नहीं है), और वास्तव में कुछ संवेदनशील डेटा को इंगित करने के लिए होता है जो तैनात होने पर कभी भी मुद्रित नहीं होना चाहिए।
celtschk

14

चेतावनियों को त्रुटियों के रूप में मानना ​​केवल आत्म-अनुशासन का एक मतलब है: आप उस चमकदार नई सुविधा का परीक्षण करने के लिए एक कार्यक्रम का संकलन कर रहे थे, लेकिन आप तब तक नहीं कर सकते जब तक आप मैला भागों को ठीक नहीं करते। कोई अतिरिक्त जानकारी Werrorप्रदान नहीं करता है, यह सिर्फ प्राथमिकताओं को बहुत स्पष्ट रूप से निर्धारित करता है:

जब तक आप मौजूदा कोड में समस्याओं को ठीक नहीं करते तब तक नया कोड न जोड़ें

यह वास्तव में मानसिकता है कि महत्वपूर्ण है, उपकरण नहीं। कंपाइलर डायग्नोस्टिक्स आउटपुट एक टूल है। MISRA (एम्बेडेड C के लिए) एक और उपकरण है। इससे कोई फर्क नहीं पड़ता कि आप किसका उपयोग करते हैं, लेकिन यकीनन संकलक चेतावनी सबसे आसान उपकरण है जिसे आप प्राप्त कर सकते हैं (यह सिर्फ एक ध्वज स्थापित करने के लिए है) और शोर अनुपात का संकेत बहुत अधिक है। इसलिए इसका उपयोग करने का कोई कारण नहीं है।

कोई भी उपकरण अचूक नहीं है। यदि आप लिखते हैं const float pi = 3.14;, तो अधिकांश उपकरण आपको यह नहीं बताएंगे कि आपने may एक खराब परिशुद्धता के साथ परिभाषित किया है जो सड़क के नीचे की समस्याओं को जन्म दे सकता है। अधिकांश उपकरण एक भौं को नहीं उठाएंगे if(tmp < 42), भले ही यह आमतौर पर ज्ञात हो कि चर को अर्थहीन नाम देना और जादू की संख्या का उपयोग करना बड़ी परियोजनाओं में आपदा का एक तरीका है। आपको यह समझना होगा कि आपके द्वारा लिखा गया कोई भी "क्विक टेस्ट" कोड सिर्फ इतना ही है: एक परीक्षण, और आपको इसे अन्य कार्यों पर जाने से पहले ठीक करना होगा, जबकि आप अभी भी इसकी कमियों को देखते हैं। यदि आप उस कोड को छोड़ देते हैं, तो डिबगिंग यदि आप दो महीने बिताने के बाद नई सुविधाएँ जोड़ रहे हैं तो यह काफी कठिन होगा।

एक बार जब आप सही मानसिकता में आ जाते हैं, तो उपयोग करने का कोई मतलब नहीं है Werror। चेतावनी के रूप में चेतावनी देने से आप एक सूचित निर्णय ले पाएंगे कि क्या यह अभी भी उस डिबग सत्र को चलाने के लिए समझ में आता है जिसे आप शुरू करने वाले थे, या इसे रद्द करने और पहले चेतावनी को ठीक करने के लिए।


3
बेहतर या बदतर के लिए, clippyजंग के लिए लाइनिंग टूल वास्तव में निरंतर "3.14" के बारे में चेतावनी देगा। यह वास्तव में डॉक्स में एक उदाहरण है । लेकिन जैसा कि आप नाम से अनुमान लगा सकते हैं, clippyआक्रामक रूप से सहायक होने में गर्व महसूस करता है।
एमके

1
@emk इस उदाहरण के लिए धन्यवाद, शायद मुझे अपने जवाब को कभी नहीं कहना चाहिए "कभी नहीं" इस तरह का। मेरे कहने का मतलब यह नहीं था कि इंप्रेसेज़ impossible मूल्यों की जाँच असंभव है, बस यह कि चेतावनियों से छुटकारा पाना सभ्य कोड गुणवत्ता की गारंटी नहीं देता है।
दिमित्री ग्रिगोरीव

त्रुटियों के रूप में आपको चेतावनी देते हुए एक बात यह है कि स्वचालित बिल्ड विफल हो जाएंगे, इस प्रकार आपको सचेत करते हुए कि कुछ गलत हो गया है। स्वचालित बिल्ड भी स्वचालित करने के लिए अनुमति देते हैं (विस्फोट 3 है ... 2 ... 1 .. :)
Móż

8

जैसा कि कोई व्यक्ति जो विरासत में प्राप्त सी कोड के साथ काम करता है, संकलक चेतावनी को सक्षम करने से फिक्सिंग का प्रस्ताव करते समय जांच करने में बहुत कमजोरी और क्षेत्रों को दिखाने में मदद मिली है। जीसीसी में उपयोग -Wallऔर -Wextraऔर यहां तक कि-Wshadow कि महत्वपूर्ण हो गया है। मैं हर एक खतरे को नहीं जा रहा हूँ, लेकिन मैं कुछ ऐसे लोगों को सूचीबद्ध करूँगा जो कोड मुद्दों को दिखाने में मदद करते हैं।

चर को पीछे छोड़ा जा रहा है

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

int foo(int a, int b)
{
   int c = 0;

   if (a > 0)
   {
        return a;
   }
   return 0;
}

बस इस संकलन के बिना -Wall या -Wextra कोई समस्या नहीं देता है। -जबकि आपको बताएगा कि cइसका कभी उपयोग नहीं किया जाता है:

foo.c: फ़ंक्शन में 'foo':

foo.c: 9: 20: चेतावनी: अप्रयुक्त चर 'c' [-व्यूज्ड-चर]

-Wextra आपको यह भी बताएगा कि आपका पैरामीटर b कुछ भी नहीं करता है:

foo.c: फ़ंक्शन में 'foo':

foo.c: 9: 20: चेतावनी: अप्रयुक्त चर 'c' [-व्यूज्ड-चर]

foo.c: 7: 20: चेतावनी: अप्रयुक्त पैरामीटर 'b' [-व्यूज्ड-पैरामीटर] int foo (int a, int b)

ग्लोबल वेरिएबल शैडोइंग

यह एक मुश्किल है और जब तक -Wshadowइस्तेमाल नहीं किया गया था तब तक नहीं दिखा । आइए उपरोक्त उदाहरण को केवल जोड़ने के लिए संशोधित करें, लेकिन स्थानीय के समान नाम के साथ एक वैश्विक होना होता है, जो दोनों का उपयोग करने की कोशिश करते समय बहुत भ्रम पैदा करता है।

int c = 7;

int foo(int a, int b)
{
   int c = a + b;
   return c;
}

जब -Whadhadow चालू किया गया था, इस मुद्दे को स्पॉट करना आसान है।

foo.c: 11: 9: चेतावनी: 'c' छाया की घोषणा एक वैश्विक घोषणा [-शडो]

foo.c: 1: 5: ध्यान दें: छायांकित घोषणा यहाँ है

प्रारूप तार

यह gcc में किसी भी अतिरिक्त झंडे की आवश्यकता नहीं है, लेकिन यह अभी भी अतीत में समस्याओं का स्रोत रहा है। एक साधारण फ़ंक्शन डेटा प्रिंट करने की कोशिश कर रहा है, लेकिन एक स्वरूपण त्रुटि इस तरह दिख सकती है:

void foo(const char * str)
{
    printf("str = %d\n", str);
}

यह स्ट्रिंग को प्रिंट नहीं करता है क्योंकि स्वरूपण ध्वज गलत है और जीसीसी खुशी से आपको बताएगा कि यह शायद वह नहीं है जो आप चाहते थे:

foo.c: फ़ंक्शन में 'foo':

foo.c: 10: 12: चेतावनी: प्रारूप '% d' प्रकार 'int' के तर्क की अपेक्षा करता है, लेकिन तर्क 2 में 'const char *' टाइप है [-रूपत =]


ये कई चीजों में से सिर्फ तीन हैं जो कंपाइलर आपके लिए दोगुना चेक कर सकते हैं। बहुत से अन्य ऐसे हैं जो एक असिंचित चर का उपयोग करते हैं जो दूसरों ने इंगित किया है।


7
एम्बेडेड दुनिया में, मुझे सबसे ज्यादा चिंता करने वाली चेतावनी " possible loss of precision" और " comparison between signed and unsigned" चेतावनी है। मुझे यह
समझाना

3
बाद के मामले में, @Mawg, मेरा मानना ​​है कि प्राथमिक कारण यह कोई त्रुटि नहीं है कि परिणाम का sizeofअहस्ताक्षरित है, लेकिन डिफ़ॉल्ट पूर्णांक प्रकार पर हस्ताक्षर किए गए हैं। sizeofपरिणाम प्रकार, size_t, आम तौर पर, जैसे, उदाहरण के लिए, संरेखण या सरणी / कंटेनर तत्व गिनती टाइप के आकार से संबंधित कुछ भी, के लिए इस्तेमाल किया, जबकि सामान्य रूप में पूर्णांक "के रूप में इस्तेमाल किया जा करने का इरादा कर रहे हैं intजब तक अन्यथा अपेक्षित"। ध्यान में रखते हुए अभी कितने लोगों को इस प्रकार उपयोग करना सिखाया जाता है intपुनरावृति करने के लिए अपने कंटेनर (की तुलना से अधिक intकरने के लिए size_t), यह एक त्रुटि मोटे तौर पर सब कुछ टूट जाएगा बना रही है। ; पी
जस्टिन टाइम -

6

यह C का एक विशिष्ट उत्तर है, और क्यों यह C से कहीं अधिक महत्वपूर्ण है।

#include <stdio.h>
int main()
{
   FILE *fp = "some string";
}

यह कोड एक चेतावनी के साथ संकलित करता है । क्या हैं और ग्रह पर हर दूसरी भाषा के बारे में त्रुटियां होनी चाहिए (विधानसभा भाषा को छोड़कर) सी में चेतावनी हैं। सी में चेतावनी लगभग हमेशा भेस में त्रुटियां हैं। चेतावनियाँ तय होनी चाहिए, दमन नहीं।

के साथ gcc, हम ऐसा करते हैं gcc -Wall -Werror

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


5

कम्पाइलर वार्निंग आपके दोस्त हैं (जोर से चिल्लाकर नहीं, जोर देने के लिए ऊपर से)।

मैं विरासत फोरट्रान -77 प्रणालियों पर काम करता हूं। कंपाइलर मुझे मूल्यवान बातें बताता है: तर्क डेटाटाइप एक सबरूटीन कॉल पर मिसमैच करता है, एक वैरिएबल को वेरिएबल में सेट करने से पहले एक स्थानीय वैरिएबल का उपयोग करने पर, अगर मेरे पास एक वैरिएबल या सबरूटीन तर्क है जिसका उपयोग नहीं किया गया है। ये लगभग हमेशा त्रुटियां हैं।

एक लंबे पोस्ट से परहेज: जब मेरा कोड साफ-सुथरा हो जाता है, तो 97% यह काम करता है। दूसरे आदमी को मैं सभी चेतावनियों के साथ कंपाइल करता हूं, डिबगर में घंटों या दिन बिताता हूं, फिर मुझसे मदद मांगता है। मैं सिर्फ चेतावनी के साथ उसका कोड संकलित करता हूं और उसे बताता हूं कि क्या ठीक करना है।


5

आपको हमेशा कंपाइलर चेतावनी को सक्षम करना चाहिए क्योंकि कंपाइलर अक्सर आपको बता सकता है कि आपके कोड में क्या गलत है। ऐसा करने के लिए, आप -Wall -Wextraसंकलक के पास जाते हैं ।

आपको आमतौर पर चेतावनियों को त्रुटियों के रूप में मानना ​​चाहिए क्योंकि चेतावनियां आमतौर पर संकेत देती हैं कि आपके कोड में कुछ गड़बड़ है। हालाँकि, इन त्रुटियों को अनदेखा करना अक्सर बहुत आसान होता है। इसलिए, उन्हें त्रुटियों के रूप में मानने से निर्माण विफल हो जाएगा ताकि आप त्रुटियों को अनदेखा न कर सकें। चेतावनियों को त्रुटियों के रूप -Werrorमें मानने के लिए, संकलक को पास करें।


4

C ++ में संकलक चेतावनी कुछ कारणों से बहुत उपयोगी है।

1 - यह आपको यह दिखाने की अनुमति देता है कि आपने कहां गलती की है जो आपके संचालन के अंतिम परिणाम को प्रभावित कर सकती है। उदाहरण के लिए यदि आपने किसी चर को प्रारंभ नहीं किया है या यदि आपने "==" के बजाय "=" रखा है (केवल उदाहरण हैं)

2 - यह आपको यह दिखाने की भी अनुमति देता है कि आपका कोड c ++ के मानक के अनुरूप नहीं है। यह उपयोगी है क्योंकि यदि कोड वास्तविक मानक के अनुरूप है तो कोड को उदाहरण के लिए अन्य प्लेटफॉर्म में स्थानांतरित करना आसान होगा।

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


4

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


4

मैंने एक बार एक बड़ी (फॉर्च्यून 50) कंपनी के लिए काम किया था जो इलेक्ट्रॉनिक परीक्षण उपकरण बनाती थी।

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

यह एक भयावह दुःस्वप्न है जब कीड़े होते हैं।

उस स्थिति के बाद, मैं भाग्यशाली था कि एक नए स्टार्टअप में पहले डेवलपर के रूप में काम पर रखा गया।

मैंने सभी बिल्ड्स के लिए 'नो वार्निंग' पॉलिसी को प्रोत्साहित किया, जिसमें कंपाइलर चेतावनी का स्तर काफी शोर-शराबे वाला था।

हमारा अभ्यास कोड के लिए #pragma वार्निंग - पुश / डिसेबल / पॉप का उपयोग करना था जो डेवलपर को निश्चित रूप से ठीक था, साथ ही डिबग स्तर पर एक लॉग स्टेटमेंट के साथ।

इस अभ्यास ने हमारे लिए अच्छा काम किया।


1
Seconded। #pragma warningयह केवल चेतावनियों को दबाता नहीं है, यह अन्य प्रोग्रामरों को जल्दी से संवाद करने के दोहरे उद्देश्यों को पूरा करता है कि कुछ जानबूझकर और आकस्मिक नहीं है, और संभावित रूप से समस्याग्रस्त क्षेत्रों को खोजने के लिए एक खोज टैग के रूप में कार्य करता है जब कुछ टूट जाता है लेकिन त्रुटियों / चेतावनियों को ठीक नहीं करता है। इसे ठीक करो।
जस्टिन टाइम -

आप सही जस्टिन हैं, ठीक इसी तरह मैंने #pragma चेतावनी देखी
जिम टेक्सास में

3

चेतावनी एक त्रुटि होने की प्रतीक्षा कर रही है। इसलिए आपको संकलक चेतावनी को सक्षम करना चाहिए और किसी भी चेतावनी को हटाने के लिए अपने कोड को साफ करना चाहिए।


3

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

मैं हमेशा अपना कोड लिखता हूं ताकि यह किसी भी चेतावनी या त्रुटियों को उत्पन्न न करे, और इसे तब तक साफ करें जब तक कि यह किसी भी बाहरी शोर को उत्पन्न किए बिना संकलित न हो जाए। जो कचरा मुझे काम करना पड़ता है, वह मुझे याद आता है, और मैं चकित रह जाता हूं, जब मुझे एक बड़ी परियोजना का निर्माण करना होता है और चेतावनी की एक धारा देखनी होती है, जहां संकलन केवल घोषणा करना चाहिए जो इसे संसाधित करता है।

मैं अपने कोड का दस्तावेज़ भी देता हूं क्योंकि मुझे पता है कि सॉफ़्टवेयर की वास्तविक जीवनकाल लागत ज्यादातर रखरखाव से आती है, इसे शुरू में लिखने से नहीं, लेकिन यह एक अलग कहानी है ...


इसे खटखटाएं नहीं, ऐसे लोगों के लिए परामर्श कार्य में अच्छा पैसा है जो ग्राहकों को कंपाइलर चेतावनी पढ़ सकते हैं।
मोद

अन्य स्रोतों चेतावनी पैदा करने से कोड ऐसा नहीं करता आवश्यक मतलब है कि लेखकों को खराब थे। इसका मतलब यह भी हो सकता है कि उन्होंने एक अलग संकलक के साथ कोड संकलित किया जो चेतावनी का एक अलग सेट उत्पन्न करता है। कोड एक संकलक पर चेतावनी के बिना संकलन कर सकता है, और दूसरे पर चेतावनी उत्पन्न कर सकता है। या शायद यह चेतावनी विकल्पों का सिर्फ एक अलग सेट है; जैसे उन्होंने इस्तेमाल किया -Wallऔर आपने इस्तेमाल किया -Wall -Wextra
celtschk

2

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

कुछ संकलक, जैसे जीसीसी, के पास "चेतावनी को त्रुटियों के रूप में" मोड को सक्रिय करने के लिए एक कमांड लाइन विकल्प है, यह एक अच्छा है, अगर क्रूर, नौसिखिए कोडर को शिक्षित करने का उपकरण है।


1

तथ्य यह है कि सी ++ compilers कोड संकलन स्वीकार करते हैं कि स्पष्ट रूप से अपरिभाषित व्यवहार में परिणाम बिल्कुल भी compilers में एक प्रमुख दोष है। वे इसे ठीक नहीं करते इसका कारण यह है कि ऐसा करने से शायद कुछ उपयोग योग्य बिल्ड टूट जाएंगे।

अधिकांश चेतावनियों में घातक त्रुटियां होनी चाहिए जो निर्माण को पूरा करने से रोकती हैं। चूक केवल त्रुटियों को प्रदर्शित करने और निर्माण को वैसे भी गलत करने के लिए है और यदि आप उन्हें चेतावनी को त्रुटियों के रूप में मानने के लिए ओवरराइड नहीं करते हैं और कुछ चेतावनियां छोड़ते हैं, तो आप संभवतः अपने कार्यक्रम के दुर्घटनाग्रस्त होने और यादृच्छिक चीजें करने के साथ समाप्त हो जाएंगे।


विडंबना यह है कि अपरिभाषित व्यवहार का एक बहुत वास्तव में चेतावनी का कारण नहीं है, लेकिन चुपचाप एक बुरा थोड़े समय बम में ठीक संकलन करता है। ; पी
जस्टिन टाइम -

1
समस्या यह है कि यदि मानक एक त्रुटि संदेश की मांग करता है, तो उस त्रुटि संदेश को उन सभी मामलों में जारी किया जाना चाहिए जहां समस्या होती है, लेकिन समस्या नहीं होने पर कभी नहीं। लेकिन अपरिभाषित व्यवहार जैसे मामलों में, यह तय करना असंभव हो सकता है। उदाहरण के लिए, निम्नलिखित कोड पर विचार करें: int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];यह कोड अपरिभाषित व्यवहार प्रदर्शित करता है यदि और केवल यदि दोनों fun1()और एक ही फ़ंक्शन निष्पादन पर fun2()वापस आ सकते हैं false। जो सच हो या न हो, लेकिन संकलनकर्ता कैसे बता सकता है?
celtschk

-2

आपको निश्चित रूप से संकलक चेतावनी को सक्षम करना चाहिए क्योंकि कुछ संकलक कुछ सामान्य प्रोग्रामिंग गलतियों की रिपोर्ट करने में खराब हैं, जिनमें निम्न शामिल हैं: -

-> इनिशियलाइज़ वेरिएबल भूल जाता है -> किसी फंक्शन से वैल्यू रिटर्न मिस हो जाता है -> प्रिन्ट और स्केन्फ फेमिली में सिंपल आर्गुमेंट्स जो स्ट्रिंग को फंक्शन को मैच नहीं कर रहा है, उसे पहले से घोषित किए बिना इस्तेमाल किया जाता है, हालाँकि c में ही होता है

ताकि इन कार्यों का पता लगाया जा सके और रिपोर्ट किया जा सके, आमतौर पर डिफ़ॉल्ट रूप से नहीं; इसलिए इस सुविधा को संकलक विकल्पों के माध्यम से स्पष्ट रूप से अनुरोध किया जाना चाहिए।


-32

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

इसका उपयोग करना या नहीं करना आपकी पसंद पर पूरी तरह निर्भर है। मैं हर समय इसका उपयोग करता हूं क्योंकि यह मुझे अपनी गलतियों को ठीक करने में मदद करता है।


19
हालांकि यह अनिवार्य नहीं है , लेकिन उनका उपयोग करने के लिए अत्यधिक सिफारिश की जाती है
Spikatrix

18
-Wall and -Werror was designed by code-refactoring maniacs for themselves.[उद्धरण वांछित]
YSC

22
ऐसा लगता है जैसे आप खुद का विरोध कर रहे हैं। यदि आप "इसका हर समय उपयोग करते हैं क्योंकि यह [आपकी] गलतियों को ठीक करने में मदद करता है," क्या यह नए प्रोग्रामर्स को सिखाने के लायक नहीं है ताकि वे इसे हर जगह से प्राप्त कर सकें? मुझे नहीं लगता कि इस सवाल पूछ रहा है या नहीं, यह है संभव के बिना संकलित करने के लिए -Wallऔर -Werror, यह सिर्फ अगर यह एक अच्छा विचार है पूछ रहा है। जो, आपके अंतिम वाक्य से, ऐसा लगता है कि आप कह रहे हैं कि यह है।
scohe001

12
जब आपके द्वारा लिखे गए कोड को बनाए रखने के साथ अधिक अनुभव प्राप्त होता है, तो इस उत्तर को फिर से देखें।
थोरबजोरन रावन एंडरसन

यह एक उपयोगी उत्तर नहीं है। ओपी प्रश्न में 4 प्रश्न चिह्न होते हैं। यह उत्तर कितने में उत्तर देता है?
एंडर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.