मैं अपवादों के लिए अनुबंध कैसे बना और लागू कर सकता हूं?


33

मैं अपनी टीम को समझाने की कोशिश कर रहा हूं isSuccessfulकि त्रुटि कोड के साथ एक बूल या एक एनम वापस करने के बजाय सी ++ में अपवादों का उपयोग करने की अनुमति देता है । हालाँकि, मैं उनकी इस आलोचना का मुकाबला नहीं कर सकता।

इस पुस्तकालय पर विचार करें:

class OpenFileException() : public std::runtime_error {
}

void B();
void C();

/** Does blah and blah. */
void B() {
    // The developer of B() either forgot to handle C()'s exception or
    // chooses not to handle it and let it go up the stack.
    C();
};

/** Does blah blah.
 *
 * @raise OpenFileException When we failed to open the file. */
void C() {
    throw new OpenFileException();
};
  1. B()फ़ंक्शन को कॉल करने वाले डेवलपर पर विचार करें । वह इसके प्रलेखन की जांच करता है और देखता है कि यह कोई अपवाद नहीं देता है, इसलिए वह कुछ भी पकड़ने की कोशिश नहीं करता है। यह कोड उत्पादन में प्रोग्राम को क्रैश कर सकता है।

  2. C()फ़ंक्शन को कॉल करने वाले डेवलपर पर विचार करें । वह दस्तावेज़ीकरण की जाँच नहीं करता है इसलिए कोई अपवाद नहीं पकड़ता है। कॉल असुरक्षित है और उत्पादन में प्रोग्राम को क्रैश कर सकता है।

लेकिन अगर हम इस तरह से त्रुटियों की जाँच करते हैं:

void old_C(myenum &return_code);

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

मैं अपवादों को सुरक्षित रूप से कैसे उपयोग कर सकता हूं, ताकि किसी प्रकार का अनुबंध हो?


4
@Sjoerd मुख्य लाभ यह है कि एक डेवलपर को कंपाइलर द्वारा रिटर्न कोड स्टोर करने के लिए फ़ंक्शन को एक चर प्रदान करने के लिए मजबूर किया जाता है; उसे इस बात से अवगत कराया जाता है कि कोई त्रुटि हो सकती है और उसे संभालना चाहिए। यह अपवादों की तुलना में असीम रूप से बेहतर है, जिसका कोई संकलन समय नहीं है।
डीबीड्रेनको

4
"उसे इसे संभालना चाहिए" - कोई जाँच नहीं है कि क्या ऐसा होता है।
सोजेरड

4
@Sjoerd यह आवश्यक नहीं है। डेवलपर को यह बताने के लिए पर्याप्त है कि त्रुटि हो सकती है और उन्हें इसके लिए जाँच करनी चाहिए। यह समीक्षकों की स्पष्ट दृष्टि में है, चाहे वे किसी त्रुटि के लिए जाँच करें या नहीं।
डीबीड्रेनको

5
टाइप-सेफ EitherResult
कंपोजेबल

5
@gardenhead क्योंकि बहुत सारे डेवलपर इसे ठीक से उपयोग नहीं करते हैं, बदसूरत कोड के साथ समाप्त होते हैं, और स्वयं के बजाय सुविधा को दोष देने के लिए आगे बढ़ते हैं। जावा में जांचा गया अपवाद फीचर एक खूबसूरत चीज है, लेकिन यह एक बुरा रैप है क्योंकि कुछ लोग इसे प्राप्त नहीं करते हैं।
चाचीओमैटिकनेक्सस

जवाबों:


47

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

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

अपनी टीम की अगुवाई करने के लिए, यह लेने के लिए सही लड़ाई नहीं हो सकती है। विशेषकर विरासत कोड के साथ नहीं। जैसा कि ऊपर दिए गए दूसरे लिंक में दिया गया है:

अपवादों को किसी भी कोड के माध्यम से प्रचारित नहीं किया जा सकता है जो अपवाद सुरक्षित नहीं है। अपवादों का उपयोग इस प्रकार होता है कि परियोजना के सभी कोड अपवाद सुरक्षित होने चाहिए।

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

यह शायद एक तर्क नहीं है जिस पर मैं प्रयास करूँगा - कम से कम तब तक नहीं जब तक कि एक नई परियोजना शुरू न हो जाए। और यहां तक ​​कि अगर आपके पास एक नई परियोजना है, तो क्या यह किसी भी विरासत कोड का उपयोग या उपयोग करने जा रहा है?


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

3
@ मुझे अपवादों के पक्ष में कुछ तर्कों के लिए ऊपर दिए लिंक देखें (मैंने अधिक विशेषज्ञ राय के साथ एक अतिरिक्त लिंक जोड़ा है)।

6
यह उत्तर हाजिर है!
डॉक्टर ब्राउन

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

26

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


अपवाद सभी जगह पकड़े जाने का इरादा नहीं है।

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

मेरे कोड में, केवल कुछ कैच स्टेटमेंट हैं - यदि कोई हो तो - मुख्य लूप के बाहर। और यह आधुनिक C ++ में आम दृष्टिकोण है।


अपवाद और वापसी कोड परस्पर अनन्य नहीं हैं।

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

सामान्य विफलताएं, जैसे कि उपयोगकर्ता द्वारा प्रदान किया गया फ़ाइल नाम मान्य है, यह जांचना अपवादों के लिए उपयोग का मामला नहीं है; इसके बजाय उन मामलों में वापसी मूल्य का उपयोग करें।

जैसा कि आप उपरोक्त उदाहरणों से देखते हैं, "फ़ाइल नहीं मिली" या तो एक अपवाद या रिटर्न कोड हो सकता है, उपयोग के मामले पर निर्भर करता है: "स्थापना का हिस्सा है" बनाम "उपयोगकर्ता एक टाइपो बना सकता है।"

इसलिए कोई पूर्ण नियम नहीं है। एक कठिन दिशानिर्देश है: यदि इसे स्थानीय स्तर पर संभाला जा सकता है, तो इसे एक वापसी मूल्य बनाएं; यदि आप इसे स्थानीय रूप से नहीं संभाल सकते हैं, तो एक अपवाद फेंक दें।


अपवादों की स्थैतिक जाँच उपयोगी नहीं है।

चूंकि अपवादों को स्थानीय स्तर पर वैसे भी नियंत्रित नहीं किया जाता है, इसलिए यह आमतौर पर महत्वपूर्ण नहीं होता है कि अपवादों को फेंका नहीं जा सकता है। एकमात्र उपयोगी जानकारी यह है कि क्या कोई अपवाद फेंका जा सकता है।

जावा में स्थैतिक जाँच होती है, लेकिन आमतौर पर इसे एक असफल प्रयोग माना जाता है, और चूंकि अधिकांश भाषाएँ - विशेष रूप से C # - में उस प्रकार की स्थैतिक जाँच नहीं होती है। यह उन कारणों के बारे में एक अच्छा पढ़ा गया है जिनके कारण C # नहीं है।

उन कारणों के लिए, C ++ ने इसके throw(exceptionA, exceptionB)पक्ष में पदावनत कर दिया है noexcept(true)। डिफ़ॉल्ट यह है कि एक फ़ंक्शन फेंक सकता है, इसलिए प्रोग्रामर को उम्मीद करनी चाहिए कि जब तक कि दस्तावेज स्पष्ट रूप से वादा नहीं करता है।


अपवाद सुरक्षित कोड लिखने से अपवाद हैंडलर लिखने से कोई लेना-देना नहीं है।

मैं इसके बजाय यह कहना चाहूंगा कि अपवाद सुरक्षित कोड लिखना सभी के बारे में है कि अपवाद हैंडलर लिखने से कैसे बचें!

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


3
" जब तक एक सामान्य अपवाद हैंडलर होता है ... आप आमतौर पर पहले से ही ठीक होते हैं। " यह अधिकांश स्रोतों का खंडन करता है, जो तनाव देता है कि अपवाद सुरक्षित कोड लिखना बहुत चुनौतीपूर्ण है।

12
@ dan1111 "लेखन अपवाद सुरक्षित कोड" का अपवाद संचालकों के लेखन से बहुत कम है। अपवाद लिखना सुरक्षित कोड RAII का उपयोग संसाधनों को इनकैप्सुलेट करने के बारे में है, "स्थानीय रूप से सभी कार्य पहले करें फिर स्वैप / चाल का उपयोग करें" और अन्य सर्वोत्तम प्रथाओं का उपयोग करें। जब आप उनके लिए उपयोग नहीं किए जाते हैं तो वे चुनौतीपूर्ण होते हैं। लेकिन "लेखन अपवाद संचालकों" उन सर्वोत्तम प्रथाओं का हिस्सा नहीं है।
सोजेरड

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

4
@AxiomaticNexus यह असम्बद्ध होने का कारण यह है कि यह आपके संपूर्ण कोड बेस में लगभग हर फ़ंक्शन को आसानी से प्रचारित कर सकता है । जब मेरी आधी कक्षाओं के सभी कार्य डेटाबेस तक पहुंचते हैं, तो उनमें से हर एक को स्पष्ट रूप से यह घोषित करने की आवश्यकता नहीं होती है कि वह एक SQLException फेंक सकता है; न ही हर कंट्रोलर मेथड है जो उन्हें कॉल करता है। यह बहुत शोर वास्तव में एक नकारात्मक मूल्य है, भले ही काम की मात्रा कितनी कम हो। Sjoerd सिर पर कील मारता है: आपके अधिकांश कोड को अपवादों से चिंतित होने की आवश्यकता नहीं है क्योंकि यह उनके बारे में वैसे भी कुछ नहीं कर सकता है
jpmc26

3
@AxiomaticNexus हाँ, क्योंकि सर्वश्रेष्ठ डेवलपर्स इतने सटीक होते हैं कि उनका कोड हमेशा हर संभव उपयोगकर्ता इनपुट को पूरी तरह से संभाल लेगा, और आप कभी भी, कभी भी, उन अपवादों को उत्पादों में नहीं देख पाएंगे। और यदि आप करते हैं, तो इसका मतलब है कि आप जीवन में असफल हैं। सच में, मुझे यह कचरा मत देना। कोई भी वह सही नहीं है, सर्वश्रेष्ठ भी नहीं। और आपके ऐप को उन त्रुटियों के सामना करने पर भी पवित्र व्यवहार करना चाहिए, भले ही "पवित्र रूप से" बंद हो और एक आधा सभ्य त्रुटि पृष्ठ / संदेश वापस आए। और क्या लगता है: यह वही चीज़ है जो आप 99% के साथ करते IOExceptionहैं । चेक किया गया विभाजन मनमाना और बेकार है।
jpmc26

8

C ++ प्रोग्रामर अपवाद विशिष्टताओं की तलाश नहीं करते हैं। वे अपवाद गारंटी की तलाश करते हैं।

मान लीजिए कि कोड के एक टुकड़े ने एक अपवाद फेंक दिया। प्रोग्रामर क्या धारणा बना सकता है जो अभी भी मान्य होगी? जिस तरह से कोड लिखा गया है, उसके अपवाद के बाद कोड क्या गारंटी देता है?

या क्या यह संभव है कि कोड का एक निश्चित टुकड़ा कभी भी फेंकने की गारंटी नहीं दे सकता है (यानी ओएस प्रक्रिया को समाप्त करने से कुछ भी कम नहीं)?

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

विभिन्न सी ++ प्रोग्रामिंग तकनीक अपवाद गारंटी को बढ़ावा देती हैं। RAII (स्कोप-आधारित संसाधन प्रबंधन) क्लीनअप कोड को निष्पादित करने और यह सुनिश्चित करने के लिए एक तंत्र प्रदान करता है कि संसाधन सामान्य मामलों और असाधारण मामलों दोनों में जारी किए जाते हैं। ऑब्जेक्ट पर संशोधन करने से पहले डेटा की एक प्रतिलिपि बनाना, किसी को उस ऑब्जेक्ट की स्थिति को पुनर्स्थापित करने की अनुमति देता है यदि ऑपरेशन विफल हो जाता है। और इसी तरह।

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

जब C ++ (उत्पादन उपयोग के लिए) में विकसित हो रहा है, तो कोई व्यक्ति विवरणों को चमक नहीं सकता है। साथ ही, बाइनरी ब्लॉब (नॉन-ओपन-सोर्स) C ++ प्रोग्रामर्स का बैन है। अगर मुझे कुछ बाइनरी बूँद को कॉल करना है, और बूँद विफल हो जाती है, तो रिवर्स इंजीनियरिंग वह है जो एक सी ++ प्रोग्रामर आगे करेगा।

संदर्भ: http://en.cppreference.com/w/cpp/language/exception#Exception_safety - रिसेप्शन सुरक्षा के अंतर्गत देखें।

C ++ अपवाद अपवादों को लागू करने में विफल रहा। बाद में अन्य भाषाओं में विश्लेषण कहता है कि अपवाद विनिर्देश केवल व्यावहारिक नहीं हैं।

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

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

संदर्भ: http://www.gotw.ca/publications/mill22.htm

C ++ 17 से शुरू [[nodiscard]]होने पर, फ़ंक्शन का उपयोग फ़ंक्शन रिटर्न मानों पर किया जा सकता है (देखें: https://stackoverflow.com/questions/39327028/can-ac-function-be-declared-such-that-the-return-value —करना to be-अनदेखा )।

इसलिए अगर मैं एक कोड परिवर्तन करता हूं और जो एक नई तरह की विफलता की स्थिति का परिचय देता है (यानी एक नए प्रकार का अपवाद), तो क्या यह एक परिवर्तन है? क्या उसे कॉल करने वाले को कोड अपडेट करने के लिए मजबूर करना चाहिए, या कम से कम बदलाव के बारे में चेतावनी देनी चाहिए?

यदि आप तर्क स्वीकार करते हैं कि C ++ प्रोग्रामर अपवाद विनिर्देशों के बजाय अपवाद गारंटी की तलाश करते हैं, तो इसका उत्तर यह है कि यदि नए प्रकार की विफलता की स्थिति किसी भी अपवाद को नहीं तोड़ती है तो कोड पहले के वादों की गारंटी देता है, यह एक परिवर्तन नहीं है।


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

@AxiomaticNexus भी अपवाद गारंटी द्वारा उत्तर दिया गया है। वास्तव में मेरा तर्क है कि विनिर्देश कभी पूरा नहीं हो सकता; गारंटी है कि हम क्या देख रहे हैं। अक्सर, हम यह पता लगाने के प्रयास में अपवाद प्रकार की तुलना करते हैं कि क्या गारंटी टूट गई थी - यह अनुमान लगाने के लिए कि क्या गारंटी अभी भी मान्य थी। अपवाद विनिर्देश कुछ प्रकारों को सूचीबद्ध करता है जिनकी आपको जांच करने की आवश्यकता है, लेकिन याद रखें कि किसी भी व्यावहारिक प्रणाली में, सूची संभवतः पूरी नहीं हो सकती है। अधिकांश समय, यह लोगों को "खाने" के शॉर्टकट को अपवाद प्रकार लेने के लिए मजबूर करता है, इसे एक और अपवाद में लपेटता है, जो अपवाद प्रकार की जाँच कठिन बनाता है
rwong

@AxiomaticNexus मैं अपवाद के उपयोग के लिए न तो बहस कर रहा हूं और न ही इसका विरोध कर रहा हूं। विशिष्ट अपवाद उपयोग एक बेस अपवाद वर्ग और कुछ व्युत्पन्न अपवाद वर्ग होने को प्रोत्साहित करता है। इस बीच, किसी को यह याद रखना होगा कि अन्य अपवाद प्रकार संभव हैं, जैसे कि C ++ STL या अन्य पुस्तकालयों से फेंके गए। यह तर्क दिया जा सकता है कि अपवाद विनिर्देश को इस मामले में काम करने के लिए बनाया जा सकता है: निर्दिष्ट करें कि मानक अपवाद ( std::exception) और आपके स्वयं के अपवाद को फेंक दिया जाएगा। लेकिन जब एक पूरे प्रोजेक्ट के लिए आवेदन किया जाता है, तो इसका मतलब है कि हर एक फ़ंक्शन का एक ही विनिर्देश होगा: शोर।
20

मैं यह बताना चाहूंगा कि जब अपवादों की बात आती है, तो C ++ और Java / C # अलग-अलग भाषाएं हैं। सबसे पहले C ++ मनमानी कोड निष्पादन या डेटा अधिलेखित करने की अनुमति देने के अर्थ में टाइप-सुरक्षित नहीं है, दूसरा C ++ एक अच्छा स्टैक ट्रेस नहीं छापता है। इन मतभेदों ने C ++ प्रोग्रामर को त्रुटि और अपवाद हैंडलिंग के मामले में अलग-अलग विकल्प बनाने के लिए मजबूर किया। इसका यह भी अर्थ है कि कुछ परियोजनाएँ वैध रूप से दावा कर सकती हैं कि C ++ उनके लिए उपयुक्त भाषा नहीं है। (उदाहरण के लिए, मैं व्यक्तिगत रूप से विचार करता हूं कि TIFF छवि डिकोडिंग को C या C ++ में लागू करने की अनुमति नहीं दी जाएगी।)
rwong

1
@rwong: C ++ मॉडल का अनुसरण करने वाली भाषाओं में अपवाद से निपटने के साथ एक बड़ी समस्या यह है कि अपवाद वस्तु catchके प्रकार पर आधारित है , जब कई मामलों में क्या मायने रखता है तो अपवाद का प्रत्यक्ष कारण नहीं है, बल्कि इसके बारे में क्या है सिस्टम स्थिति। दुर्भाग्य से, एक अपवाद का प्रकार आम तौर पर इस बारे में कुछ नहीं कहता है कि क्या इसने कोड को एक आंशिक रूप से अद्यतन (और इस प्रकार अमान्य) स्थिति में एक वस्तु को छोड़ने के तरीके को अचानक से एक कोड से बाहर कर दिया।
सुपरकैट

4

सी () फ़ंक्शन को कॉल करने वाले डेवलपर पर विचार करें। वह दस्तावेज़ीकरण की जाँच नहीं करता है इसलिए कोई अपवाद नहीं पकड़ता है। कॉल असुरक्षित है

यह पूरी तरह से सुरक्षित है। उसे हर जगह अपवादों को पकड़ने की ज़रूरत नहीं है, वह बस कोशिश / पकड़ को एक ऐसी जगह पर फेंक सकता है जहाँ वह वास्तव में इसके बारे में कुछ उपयोगी कर सकता है। यह केवल असुरक्षित है अगर वह इसे एक धागे से बाहर लीक करने की अनुमति देता है, लेकिन आमतौर पर ऐसा होने से रोकना मुश्किल नहीं है।


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

1
@cmaster उसे एक अपवाद से बाहर आने की उम्मीद नहींC() है एक बड़ी गलती है। C ++ में डिफ़ॉल्ट यह है कि कोई भी फ़ंक्शन फेंक सकता है - इसे noexcept(true)संकलक को अन्यथा बताने के लिए एक स्पष्ट आवश्यकता होती है । इस वादे के अभाव में, एक प्रोग्रामर को यह मान लेना चाहिए कि कोई फ़ंक्शन फेंक सकता है।
Sjoerd

1
@cmaster यह उनकी अपनी गलती है और C () के लेखक से कोई लेना देना नहीं है। अपवाद सुरक्षा एक चीज़ है, उसे इसके बारे में सीखना चाहिए और उसका पालन करना चाहिए। यदि वह किसी ऐसे फ़ंक्शन को कॉल करता है जिसे वह नहीं जानता है कि वह अस्पष्ट है, तो उसे अच्छी तरह से संभालना चाहिए कि अगर यह फेंकता है तो क्या होता है। यदि उसे noexcept की आवश्यकता है, तो उसे एक कार्यान्वयन खोजना चाहिए जो कि है।
डेडएमजी

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

@cmaster यह एक नई परियोजना के बारे में है - स्वीकृत उत्तर पर पहली टिप्पणी देखें। इसलिए कोई मौजूदा फ़ंक्शन नहीं हैं जो टूट जाएगा, क्योंकि कोई मौजूदा फ़ंक्शन नहीं हैं।
सोजेरड

3

यदि आप एक महत्वपूर्ण प्रणाली का निर्माण कर रहे हैं, तो अपनी टीम के नेतृत्व की सलाह पर विचार करें और अपवादों का उपयोग न करें। यह लॉकहीड मार्टिन के जॉइंट स्ट्राइक फाइटर एयर व्हीकल C ++ कोडिंग मानकों में AV Rule 208 है । दूसरी ओर, MISRA C ++ दिशानिर्देशों के बारे में बहुत विशिष्ट नियम हैं जब अपवाद और उपयोग नहीं किए जा सकते हैं यदि आप MISRA-अनुरूप सॉफ़्टवेयर सिस्टम बना रहे हैं।

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

अंततः, मैं यह तर्क देता हूं कि अनुबंध और रक्षात्मक प्रोग्रामिंग द्वारा डिजाइन , स्थैतिक विश्लेषण के साथ मिलकर अपवादों की तुलना में महत्वपूर्ण सॉफ्टवेयर सिस्टम के लिए सुरक्षित है।

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