2010-05-27 14 views
39

मैं हाल ही में देखा कि बढ़ावा program_options पुस्तकालय एक logic_error फेंकता है तो कमांड लाइन इनपुट अन-parsable था। इसने मेरी धारणाओं को logic_error बनाम runtime_error के बारे में चुनौती दी।std :: के बारे में उलझन में runtime_error बनाम std :: logic_error

मुझे लगता है कि तर्क त्रुटियां (logic_error और इसकी व्युत्पन्न कक्षाएं) ऐसी समस्याएं थीं जो आंतरिक विफलताओं के परिणामस्वरूप प्रोग्राम इनवेरिएंट का पालन करती थीं, अक्सर आंतरिक एपीआई के अवैध तर्कों के रूप में। इस संदर्भ में वे काफी हद तक ASSERT के लिए बराबर है, लेकिन जारी किया कोड में इस्तेमाल किया जा करने के लिए होती हैं (ASSERT के जो आम तौर पर जारी किया गया कोड में संकलित नहीं कर रहे हैं के विपरीत है।) वे स्थितियों में, जहां यह डिबग में अलग सॉफ्टवेयर घटक को एकीकृत करने के अव्यवहार्य है में उपयोगी होते हैं/परीक्षण बनाता है या विफलता के परिणाम ऐसे हैं कि उपयोगकर्ता को अमान्य invariant स्थिति के बारे में रनटाइम प्रतिक्रिया देना महत्वपूर्ण है।

इसी तरह, मैंने सोचा था कि runtime_error रों विशेष रूप से हुई क्रम स्थितियों से प्रोग्रामर के नियंत्रण के बाहर: आई/ओ त्रुटियों, अमान्य उपयोगकर्ता इनपुट, आदि

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

मैं गलत कहां जा रहा हूं? क्या आप अपवाद टाइपिंग के बूस्ट मॉडल से सहमत हैं?

+1

आप इस प्रश्न को बूस्ट उपयोगकर्ता मेलिंग सूची पर क्यों नहीं पूछते हैं? –

उत्तर

30

इस मामले में, मुझे लगता है कि (कम से कम अधिकांश भाग के लिए) तुम सही हो और यह गलत है।

वर्ग logic_error ऐसे तार्किक पूर्व शर्त या वर्ग अपरिवर्तनशीलताओं के उल्लंघन के रूप में शायद पता लगाने योग्य पहले कार्यक्रम कार्यान्वित त्रुटियों, रिपोर्ट करने के लिए अपवाद के रूप में फेंक दिया वस्तुओं के प्रकार परिभाषित करता है: मानक logic_error के रूप में वर्णन करता है।

एक कमांड लाइन तर्क जिसे पार्स नहीं किया जा सकता है, वह बहुत अच्छी तरह से फिट नहीं लगता है।

वर्ग runtime_error शायद पता लगाने योग्य केवल जब कार्यक्रम कार्यान्वित त्रुटियों की रिपोर्ट के अपवादों के अनुसार फेंक दिया वस्तुओं के प्रकार परिभाषित करता है:

इसके विपरीत, यह runtime_error के रूप में वर्णन करता है।

लगता है कि एक बेहतर फिट होने के लिए।

5

C++ 0x स्टैंडर्ड की वर्तमान मसौदा कहता है (खंड 19.2):

1) त्रुटि मॉडल में में परिलक्षित इन कक्षाओं (यानी अपवाद टाइप), त्रुटियों दो भागों में विभाजित कर रहे हैं व्यापक श्रेणियां: तर्क त्रुटियां और रनटाइम त्रुटियां।

2) तर्क त्रुटियों की ख़ास विशेषता है कि वे कारण कार्यक्रम के आंतरिक तर्क में त्रुटियों के लिए कर रहे है। सिद्धांत रूप में, वे रोकथाम योग्य हैं।

3) इसके विपरीत, क्रम त्रुटियों की वजह से कार्यक्रम के दायरे से बाहर की घटनाओं रहे हैं। वे अग्रिम में भविष्यवाणी नहीं कर सकते हैं।

साथ में उद्धरण अन्य उत्तर यह बताता है कि क्यों Boost.ProgramOptions एक std :: एक 'त्रुटि शायद पता लगाने योग्य पहले कार्यक्रम कार्यान्वित' की वजह से रोके त्रुटियों के लिए logic_error फेंकता में से एक में उद्धृत के साथ

+0

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

+0

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

+0

यह इस बात पर जोर देगा कि प्रोग्राम को प्रासंगिक प्रकार के इनपुट की जांच/सफाई करने की अपेक्षा की जा सकती है या नहीं। अगर ऐसी उम्मीद अनुचित है, तो यह कार्यक्रम के दायरे से बाहर है। लेकिन "स्कोप" लाइब्रेरी कोड की अपेक्षाओं के रूप में परिभाषित किया गया है, न कि आपके प्रोग्राम के डिज़ाइन। – Grault

8

एक शुद्ध मानक दृष्टिकोण से, आप सही हैं। प्रोग्राम_ऑप्शन को runtime_error या logic_error से प्राप्त कक्षाओं को फेंकना चाहिए, इस पर निर्भर करता है कि त्रुटि रनटाइम या लॉजिकल है या नहीं। (मैंने वर्तमान अपवादों के लिए इस तरह के विचार वर्गीकरण को निर्धारित करने के लिए वर्तमान कोड की समीक्षा नहीं की थी)।

एक व्यावहारिक दृष्टिकोण से, मुझे अभी तक सी ++ कोड नहीं देखना है जो अपवाद logic_error या runtime_error पर आधारित निर्णय लेता है। आखिरकार, एकमात्र कारण है कि आप logic_error फेंकने के विरोध में दावा फ़ाइल देने के विरोध में हैं, यदि आप किसी भी तरह से पुनर्प्राप्त करने का प्रयास करना चाहते हैं, और यह रनटाइम त्रुटि से पुनर्प्राप्ति से अलग नहीं है। व्यक्तिगत रूप से, मैं logic_error बनाम runtime_error जावा में चेक अपवादों के समान ही देखता हूं - सैद्धांतिक रूप से अच्छा, लेकिन अभ्यास में उपयोगी नहीं है। जिसका अर्थ है, शायद, मैं केवल program_options::errorexception से प्राप्त करूंगा। यही है, जब मुझे लगता है कि 'खाली समय' हर कोई बात करता रहता है।

+2

मेरा मानना ​​है कि आपको logic_error को जाने और कार्यक्रम को समाप्त करने देना चाहिए (ताकि पीड़ित डेवलपर्स को डीबग/कोर जानकारी भेज सके), जबकि रनटाइम आतंक को पकड़ लिया जाना चाहिए और रिपोर्ट करें: "आपने मुझे अनदेखी जानकारी दी है, कृपया कोशिश करें फिर।" –

1

उपयोगकर्ता यह सत्यापित कर सकता है कि फ़ाइल मौजूद है, प्रोग्राम चलाएं, और अचानक जानें कि फ़ाइल हटा दी गई है। यही कारण है कि एक I/O समस्या हमेशा runtime_error है। राज्य की समस्याएं runtime_errors हैं, भले ही कॉलर चेक कर सके, क्योंकि एक और धागा समस्या का कारण बन सकता है।

logic_error तब होता है जब किसी फ़ंक्शन के तर्क गलत होते हैं। यह केवल है जो चीजों के लिए मजबूत प्रकार-जांच के साथ पहले पकड़ा जा सकता था।

तो, "गायब फ़ाइल" runtime_error है, लेकिन "अनुचित रूप से स्वरूपित फ़ाइल नाम" logic_error है।

तकनीकी तौर पर, एक तार्किक त्रुटि के भीतर एक समारोह एक logic_error भी है, लेकिन अगर आप बहुत चालाक अपने खुद के समारोह के अंदर इसके लिए परीक्षण करने के लिए है, तो आप बहुत चालाक पहली जगह में यह को रोकने के लिए किया जाना चाहिए।

+0

"यदि आप अपने स्वयं के फ़ंक्शन के अंदर परीक्षण करने के लिए पर्याप्त स्मार्ट हैं, तो आपको इसे पहले स्थान पर रोकने के लिए पर्याप्त स्मार्ट होना चाहिए" - इससे कई धारणाएं मिलती हैं, जिनमें आपके सभी कोड – minexew

+0

पर नियंत्रण है 3 डोमेन: 1) आपके फ़ंक्शन का कॉलर, 2) आपका फ़ंक्शन, और 3) आपके फ़ंक्शन द्वारा बुलाए गए पुस्तकालय। यदि (1) बुरी इनपुट के साथ कॉल (2), (2) 'logic_error' फेंक देना चाहिए। अगर कुछ गलत हो गया है (1) परीक्षण नहीं कर सका (उदा। एक फ़ाइल अचानक किसी अन्य प्रक्रिया द्वारा हटा दी जाती है), (2) 'रनटाइम' फेंकना चाहिए। यह स्पष्ट है, है ना? लेकिन क्या होता है यदि (2) कॉल (3) अनुचित तरीके से? यह एक तर्कसंगत त्रुटि है (2), इसलिए (3) 'तर्क' फेंक सकता है। मैं कह रहा हूं कि (2) एक 'तर्क' को फेंक दिया जाता है (3), (2) को 'रनटाइम' के रूप में फिर से फेंकना चाहिए, लेकिन यह बेहतर है कि पहली बार त्रुटि न हो। – cdunn2001

0

IMO,

  • std::logic_error एक उपयोगकर्ता सी ++ प्रोग्राम तर्क जानबूझकर द्वारा फेंक दिया है। एक उपयोगकर्ता कार्यक्रम द्वारा भविष्यवाणी की।

  • std::runtime_error एक सी ++ क्रम (या langauge का मुख्य भाग होता ...) सार निचले स्तर त्रुटियों के द्वारा फेंक दिया है। किसी भी उपयोगकर्ता कोड के बिना किसी भी इरादे के बिना बस होता है।

संबंधित मुद्दे