संदर्भ के लिए, मैं Google में काम करने वाला एक क्लैंग डेवलपर हूं। Google पर, हमने अपने C ++ डेवलपर्स के सभी (अनिवार्य रूप से) क्लैंग के डायग्नोस्टिक्स को रोलआउट किया है, और हम क्लैंग की चेतावनियों को त्रुटियों के रूप में भी मानते हैं। एक क्लैंग डेवलपर और क्लैंग के डायग्नोस्टिक्स के बड़े उपयोगकर्ताओं में से एक के रूप में, मैं इन झंडों पर कुछ प्रकाश डालने की कोशिश करूँगा और उनका उपयोग कैसे किया जा सकता है। ध्यान दें कि मैं जो कुछ भी वर्णन कर रहा हूं वह क्लैंग पर सामान्य रूप से लागू है, और सी, सी ++, या ऑब्जेक्टिव-सी के लिए विशिष्ट नहीं है।
टीएल; डीआर संस्करण: आप जिस भी नए कोड को विकसित कर रहे हैं, उस पर कृपया -Wall
और -Werror
कम से कम उपयोग करें । हम (कंपाइलर डेवलपर्स) अच्छे कारणों के लिए यहां चेतावनी जोड़ते हैं: वे बग ढूंढते हैं। यदि आपको कोई चेतावनी मिलती है जो आपके लिए बग को पकड़ती है, तो इसे भी चालू करें। -Wextra
यहां अच्छे उम्मीदवारों के एक समूह के लिए प्रयास करें। यदि उनमें से एक भी आपके लिए लाभप्रद रूप से उपयोग करने के लिए बहुत शोर है, तो बग दर्ज करें । यदि आप एक "स्पष्ट" बग वाला कोड लिखते हैं, लेकिन संकलक ने इसके बारे में चेतावनी नहीं दी है, तो बग दर्ज करें।
अब लंबे संस्करण के लिए। झंडे की ग्रुपिंग की चेतावनी देने वाली पहली पृष्ठभूमि। क्लैंग (और जीसीसी में एक सीमित सीमा तक) में चेतावनी के "समूह" हैं। कुछ जो इस चर्चा के लिए प्रासंगिक हैं:
- ऑन-बाय-डिफ़ॉल्ट: ये चेतावनी हमेशा तब तक होती है जब तक आप उन्हें स्पष्ट रूप से अक्षम नहीं करते हैं।
-Wall
: ये चेतावनी है कि डेवलपर्स को अपने मूल्य और कम झूठी-सकारात्मक दर दोनों में उच्च विश्वास है।
-Wextra
: ये ऐसी चेतावनी हैं जिन्हें मूल्यवान और ध्वनि माना जाता है (यानी, वे छोटी गाड़ी नहीं हैं), लेकिन उनमें उच्च झूठी-सकारात्मक दर या सामान्य दार्शनिक आपत्तियां हो सकती हैं।
-Weverything
: यह एक पागल समूह है जो
क्लैंग में हर चेतावनी को शाब्दिक रूप से सक्षम करता है । अपने कोड पर इसका उपयोग न करें। यह क्लैंग डेवलपर्स के लिए कड़ाई से या उन चेतावनियों की खोज के लिए है ।
उपर्युक्त दो प्राथमिक मानदंड हैं जो क्लैंग में चेतावनी देते हैं कि कौन सी मार्गदर्शिका है, और आइए स्पष्ट करें कि वास्तव में इनका क्या मतलब है। पहले चेतावनी की एक विशेष घटना का संभावित
मूल्य है। यह उपयोगकर्ता (डेवलपर) को अपेक्षित लाभ है जब चेतावनी आग देती है और
कोड के साथ किसी समस्या की सही पहचान करती है।
दूसरा मानदंड झूठी-सकारात्मक रिपोर्टों का विचार है । ये ऐसी परिस्थितियां हैं जहां चेतावनी कोड पर फायर करती है, लेकिन संभावित समस्या का उल्लेख वास्तव में कार्यक्रम के संदर्भ या किसी अन्य बाधा के कारण नहीं होता है। कोड के बारे में चेतावनी दी वास्तव में सही ढंग से व्यवहार कर रहा है। ये विशेष रूप से खराब होते हैं जब चेतावनी को उस कोड पैटर्न पर आग लगाने का इरादा नहीं था। इसके बजाय, यह चेतावनी के कार्यान्वयन में कमी है जो इसे वहां आग लगाने का कारण बनता है।
क्लैंग चेतावनियों के लिए, मूल्य शुद्धता के संदर्भ में होना आवश्यक है , न कि शैली, स्वाद, या कोडिंग सम्मेलनों के संदर्भ में। यह उपलब्ध चेतावनियों के समूह को सीमित करता है, अक्सर अनुरोधित चेतावनियों को छोड़कर जैसे चेतावनी जब भी {}
किसी if
कथन के मुख्य भाग के आसपास उपयोग नहीं की जाती है । क्लैंग भी झूठी-सकारात्मकता के बहुत असहिष्णु हैं । अधिकांश अन्य संकलक के विपरीत, यह निर्माण, उपस्थिति या अतिरिक्त '()', कलाकारों, या यहां तक कि प्रीप्रोसेसर मैक्रोज़ की सटीक वर्तनी सहित गलत सकारात्मकता को पहचानने के लिए अविश्वसनीय स्रोतों की जानकारी का उपयोग करेगा।
अब हम क्लैंग से कुछ वास्तविक दुनिया के उदाहरण चेतावनी लेते हैं, और देखें कि उन्हें कैसे वर्गीकृत किया जाता है। सबसे पहले, एक डिफ़ॉल्ट चेतावनी:
% nl x.cc
1 class C { const int x; };
% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
^
1 warning generated.
यहाँ इस चेतावनी को प्राप्त करने के लिए किसी ध्वज की आवश्यकता नहीं थी। तर्क यह है कि यह कोड वास्तव में सही नहीं है, चेतावनी को उच्च मूल्य देता है , और चेतावनी केवल कोड पर आग लगाती है कि क्लैंग इस बाल्टी में गिर सकता है, यह एक शून्य झूठी-सकारात्मक दर देता है।
% nl x2.cc
1 int f(int x_) {
2 int x = x;
3 return x;
4 }
% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
1 warning generated.
क्लैंग को -Wall
इस चेतावनी के लिए ध्वज की आवश्यकता है । कारण यह है कि वहाँ एक गैर-तुच्छ मात्रा में कोड है जिसका उपयोग (अच्छे या बीमार के लिए) किया गया है, जिस कोड पैटर्न के बारे में हम जानबूझकर एक अनैतिक मूल्य का उत्पादन करने के बारे में चेतावनी दे रहे हैं । दार्शनिक रूप से, मुझे इसमें कोई मतलब नहीं दिखता है, लेकिन कई अन्य असहमत हैं और राय में इस अंतर की वास्तविकता है जो -Wall
ध्वज के तहत चेतावनी देती है
। इसका अभी भी बहुत अधिक मूल्य है और बहुत कम
झूठी-सकारात्मक दर है, लेकिन कुछ कोडबेस पर यह एक गैर-स्टार्टर है।
% nl x3.cc
1 void g(int x);
2 void f(int arr[], unsigned int size) {
3 for (int i = 0; i < size; ++i)
4 g(arr[i]);
5 }
% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for (int i = 0; i < size; ++i)
~ ^ ~~~~
1 warning generated.
इस चेतावनी के लिए -Wextra
ध्वज की आवश्यकता है । कारण यह है कि बहुत
बड़े कोडबेस हैं जहां तुलनाओं पर गलत मिलान का संकेत बेहद आम है। हालांकि यह चेतावनी कुछ बग ढूंढती है, जब उपयोगकर्ता लिखता है तो कोड के बग की संभावना कम होती है। परिणाम एक अत्यंत उच्च झूठी-सकारात्मक दर है। हालांकि, जब अजीब पदोन्नति नियमों के कारण एक कार्यक्रम में एक बग होता है, तो यह अक्सर बहुत ही सूक्ष्म होता है इस चेतावनी को बनाते हुए
जब यह एक झंडे को अपेक्षाकृत उच्च मूल्य देता है । परिणामस्वरूप, क्लैंग इसे प्रदान करता है और इसे एक ध्वज के नीचे उजागर करता है।
आमतौर पर, चेतावनी -Wextra
झंडे के बाहर लंबे समय तक नहीं रहती है । क्लैंग चेतावनी को लागू नहीं करने के लिए बहुत कोशिश करता है जो नियमित उपयोग और परीक्षण नहीं देखता है। द्वारा चालू की गई अतिरिक्त चेतावनियाँ -Weverything
आमतौर पर सक्रिय विकास के तहत या सक्रिय बग के साथ चेतावनी होती हैं। या तो उन्हें तय किया जाएगा और उपयुक्त झंडों के नीचे रखा जाएगा, या उन्हें हटा दिया जाना चाहिए।
अब जब हमें यह समझ है कि ये चीजें क्लैंग के साथ कैसे काम करती हैं, तो आइए मूल प्रश्न पर वापस जाने की कोशिश करें: आपको अपने विकास के लिए क्या चेतावनी देनी चाहिए? जवाब है, दुर्भाग्य से, यह निर्भर करता है। आपकी स्थिति के लिए कौन सी चेतावनियाँ सर्वोत्तम रूप से काम करती हैं, यह निर्धारित करने में मदद करने के लिए निम्नलिखित प्रश्नों पर विचार करें।
- क्या आपके पास अपने सभी कोड पर नियंत्रण है, या इसमें से कुछ बाहरी है?
- तुम्हारा लक्ष्य क्या है? बग्स को पकड़ना, या बेहतर कोड लिखना?
- आपकी झूठी-सकारात्मक सहिष्णुता क्या है? क्या आप नियमित रूप से मौन चेतावनी के लिए अतिरिक्त कोड लिखने के लिए तैयार हैं?
सबसे पहले और सबसे महत्वपूर्ण, यदि आप कोड को नियंत्रित नहीं करते हैं, तो वहां पर अतिरिक्त चेतावनियों को बदलने की कोशिश न करें। कुछ बंद करने के लिए तैयार रहें। दुनिया में बहुत बुरा कोड है, और आप इसे ठीक करने में सक्षम नहीं हो सकते हैं। वह ठीक है। आपके द्वारा नियंत्रित कोड पर अपने प्रयासों को केंद्रित करने का एक तरीका खोजने के लिए काम करें ।
इसके बाद, यह पता करें कि आप अपनी चेतावनियों से क्या चाहते हैं। यह अलग-अलग लोगों के लिए अलग-अलग है। क्लैंग बिना किसी विकल्प के बगैर चेतावनी देने की कोशिश करेंगे, जैसे कि कीड़े, या कोड पैटर्न जिनके लिए हमारे पास लंबे ऐतिहासिक उदाहरण हैं, जो बताते हैं कि बग दर बहुत अधिक है। सक्षम करने से -Wall
आप क्लैग डेवलपर्स C ++ कोड में देखी गई सबसे सामान्य गलतियों को पकड़ने के लिए लक्षित चेतावनियों का अधिक आक्रामक सेट प्राप्त करने जा रहे हैं। लेकिन इन दोनों के साथ
झूठी-सकारात्मक दर काफी कम रहनी चाहिए।
अंत में, यदि आप हर मोड़ पर * असत्य-सकारात्मक * को मौन करने के लिए पूरी तरह से तैयार हैं, तो जाएं -Wextra
। यदि आप ऐसे चेतावनी नोटिस करते हैं जो बहुत सारे वास्तविक बग को पकड़ रहे हैं, लेकिन जो मूर्खतापूर्ण या निरर्थक झूठी सकारात्मकता है, उन्हें दर्ज करें। हम लगातार और अधिक और बग खोजने तर्क के और अधिक लाने में पेश करने के लिए तरीके खोजने के लिए काम कर रहे हैं -Wextra
में -Wall
जहाँ हम झूठी सकारात्मक बच सकते हैं।
कई लोग पाएंगे कि इनमें से कोई भी विकल्प उनके लिए उचित नहीं है। Google पर, हमने -Wall
चेतावनी के उल्लंघन वाले कई मौजूदा कोड के कारण कुछ चेतावनियों को बंद कर दिया है । हमने कुछ चेतावनियों को भी स्पष्ट रूप से बदल दिया है, भले ही वे इसके द्वारा सक्षम न हों -Wall
, क्योंकि उनके पास हमारे लिए विशेष रूप से उच्च मूल्य है। आपका माइलेज अलग-अलग होगा, लेकिन संभवतः इसी तरह से अलग-अलग होगा। यह अक्सर सभी के बजाय कुछ प्रमुख चेतावनियों को सक्षम करने के लिए बेहतर हो सकता है
-Wextra
।
मैं सभी को -Wall
किसी भी गैर-विरासत कोड को चालू करने के लिए प्रोत्साहित करूंगा । नए कोड के लिए, यहां चेतावनी लगभग हमेशा मूल्यवान होती है, और वास्तव में विकासशील कोड के अनुभव को बेहतर बनाते हैं। इसके विपरीत, मैं सभी को प्रोत्साहित करूंगा कि वे
झंडे को आगे न बढ़ने दें -Wextra
। यदि आपको एक क्लैंग चेतावनी मिलती है -Wextra
जिसमें शामिल नहीं है लेकिन जो आपके लिए सभी मूल्यवान साबित होती है , तो बस एक बग दर्ज करें और हम संभवतः इसे नीचे रख सकते हैं -Wextra
। क्या आप स्पष्ट रूप से चेतावनियों के कुछ सबसेट को सक्षम -Wextra
करते हैं, यह आपके कोड, आपकी कोडिंग शैली पर बहुत अधिक निर्भर करेगा, और क्या उस सूची को बनाए रखना सब कुछ उजागर करने से आसान है -Wextra
।
चेतावनी (जो दोनों शामिल की ओपी की सूची की -Wall
और -Wextra
) केवल निम्न चेतावनी रहे हैं नहीं उन दो समूहों के अंतर्गत आने वाले (या डिफ़ॉल्ट रूप से चालू)। पहला समूह इस बात पर जोर देता है कि स्पष्ट चेतावनी झंडे पर अधिक निर्भरता खराब क्यों हो सकती है: इनमें से कोई भी क्लैंग में लागू नहीं है! वे केवल GCC संगतता के लिए कमांड लाइन पर स्वीकार किए जाते हैं।
-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
मूल सूची में अनावश्यक चेतावनियों की अगली बाल्टी वे हैं जो उस सूची में दूसरों के साथ बेमानी हैं:
-Wformat-nonliteral
-- का भाग -Wformat=2
-Wshorten-64-to-32
-- का भाग -Wconversion
-Wsign-conversion
-- का भाग -Wconversion
चेतावनियों का एक चयन भी है जो स्पष्ट रूप से अलग हैं। ये बग्गी या गैर-बग्गी कोड के बजाय भाषा बोली वेरिएंट के साथ सौदा करते हैं। के अपवाद के साथ -Wwrite-strings
, ये सभी क्लैंग द्वारा प्रदान किए गए भाषा एक्सटेंशन के लिए चेतावनी हैं। क्या क्लैंग उनके उपयोग के बारे में चेतावनी देता है, यह विस्तार की व्यापकता पर निर्भर करता है। क्लेंग का उद्देश्य जीसीसी संगतता है, और इसलिए कई मामलों में यह आसान है कि अंतर्निहित भाषा एक्सटेंशन के साथ व्यापक उपयोग में हैं। -Wwrite-strings
, जैसा कि ओपी पर टिप्पणी की गई है, जीसीसी से एक संगतता ध्वज है जो वास्तव में कार्यक्रम शब्दार्थ को बदलता है। मुझे इस झंडे पर गहरा अफसोस है, लेकिन हमें अब इसे विरासत के कारण इसका समर्थन करना होगा।
-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
शेष विकल्प जो वास्तव में संभावित दिलचस्प चेतावनियों को सक्षम कर रहे हैं वे हैं:
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
इसका कारण यह नहीं है -Wall
या -Wextra
हमेशा स्पष्ट नहीं है। इनमें से कई लोगों के लिए, वे वास्तव में जीसीसी चेतावनी (पर आधारित होते हैं -Wconversion
,
-Wshadow
आदि) और इस तरह बजना जीसीसी के व्यवहार की नकल करने की कोशिश करता है। हम धीरे-धीरे इनमें से कुछ को अधिक बारीक-बारीक और उपयोगी चेतावनियों में तोड़ रहे हैं। इसके बाद उच्च स्तरीय चेतावनी समूहों में से एक में इसे बनाने की उच्च संभावना है। जिसके अनुसार, लेने के लिए एक चेतावनी पर, -Wconversion
है तो यह है कि यह संभावना है अपने स्वयं के "शीर्ष स्तरीय" निकट भविष्य के लिए श्रेणी रहेगा व्यापक। कुछ अन्य चेतावनियाँ जो GCC की हैं, लेकिन जिनकी कम कीमत और उच्च झूठी-सकारात्मक दरें हैं, उन्हें इसी तरह के नो-मैन्स-लैंड में पुनः प्राप्त किया जा सकता है।
अन्य कारणों से ये बड़ी बाल्टियों में से एक में नहीं हैं, इसमें साधारण बग, बहुत महत्वपूर्ण झूठी-सकारात्मक समस्याएं और विकास चेतावनी शामिल हैं। मैं उन लोगों के लिए बग दर्ज करने जा रहा हूं जिनकी मैं पहचान कर सकता हूं। उन्हें आखिरकार एक उचित बड़े बाल्टी ध्वज में पलायन करना चाहिए या क्लैंग से हटा दिया जाना चाहिए।
मुझे उम्मीद है कि यह क्लैंग के साथ चेतावनी की स्थिति को स्पष्ट करता है और उन लोगों के लिए कुछ अंतर्दृष्टि प्रदान करता है जो अपने उपयोग, या कंपनी के उपयोग के लिए चेतावनी का एक सेट लेने की कोशिश कर रहे हैं।