2008-12-15 11 views
9

मुझे एक प्रोजेक्ट में कुछ कोड मिला जो इस तरह दिखता है:क्या मुख्य (...) में अपवादों को पकड़ने के लिए यह समझ में आता है?

int main(int argc, char *argv[]) 
{ 
    // some stuff 

try { 
    theApp.Run(); 
} catch (std::exception& exc) { 
    cerr << exc.what() << std::endl; 
    exit(EXIT_FAILURE); 
} 
return (EXIT_SUCCESS); 
} 

मुझे समझ में नहीं आता कि अपवाद क्यों पकड़े जा रहे हैं। यदि वे नहीं थे, तो एप्लिकेशन बस बाहर निकल जाएगा और अपवाद मुद्रित किया जाएगा।

क्या आप यहां अपवादों को पकड़ने के लिए कोई अच्छा कारण देखते हैं?


संपादित करें: मैं सहमत हूं कि अपवाद त्रुटि मुद्रित करना अच्छा है। हालांकि, अपवाद को फिर से सुधारना बेहतर नहीं होगा? मुझे यह महसूस हो रहा है कि हम इसे यहां निगल रहे हैं ...

+0

इसे कैसे निगल लिया जा सकता है? कोड अपवाद संदेश प्रिंट करता है, और फिर बाहर निकलता है। आप और क्या कर सकते हैं यदि आप अपवाद को पुनर्स्थापित करते हैं, तो इसे कौन देखेगा? इसे पकड़ा जाएगा? यह कार्यक्रम के प्रवेश बिंदु है, आखिरकार। – jalf

उत्तर

15

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

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

मुख्य में अपवाद Rethrowing, सीमित उपयोग की मुझे लगता है के बाद से आप पहले से ही संदर्भ में यह मूल रूप से फेंक दिया गया था खो दिया है। मुझे लगता है कि डीबगर में एक अपरिपक्व अपवाद को फँसाना सिर्फ std :: cerr में गलती को लॉग करने की तुलना में शोर है, इसलिए अगर लॉगिंग खोने का मौका मिलता है तो फिर से चलना स्मार्ट कदम होगा।

यदि आप डिबगर मोड में अप्रत्याशित परिस्थितियों को फंसाने के लिए डीबगर चाहते हैं, जो रिहाई मोड में एक अपवाद फेंक देता है जिसके परिणामस्वरूप अंततः बाहर निकलता है, तो अपवाद को छोड़ने के अलावा ऐसा करने के अन्य तरीके भी हैं ताकि डीबगर इसे देख सके ।उदाहरण के लिए, आप जोर मैक्रोज़ का उपयोग कर सकते हैं। बेशक, यह अप्रत्याशित और अप्रत्याशित स्थितियों में मदद नहीं करता है, जैसे हार्डवेयर अपवाद यदि आप .NET पर SEH का उपयोग कर रहे हैं।

6

आप क्यों कहते हैं कि अपवाद मुद्रित किया जाएगा? यह C++ रनटाइम का सामान्य व्यवहार नहीं है। सबसे अच्छा, आप उम्मीद कर सकते हैं कि इसका प्रकार मुद्रित हो जाता है।

इसके अतिरिक्त, यह प्रोग्राम "विफलता" स्थिति छोड़ देता है, जबकि एक अपवाद एक समाप्ति-दर-निरस्त स्थिति (यानी निकास कोड में संकेतित सिग्नल के साथ) हो सकता है।

+0

आप सही हैं, मैंने गलती से सोचा कि अपवाद मुद्रित किया जाएगा। यह मामला नहीं है। – Barth

3

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

+0

यह केवल एक अच्छा विचार है, जब तक कि आपको पहली बार कुछ रहस्यमय अपवाद को डीबग करना पड़ता है, जिसे नरक से फेंक दिया जाता है, जानता है कि ... :) – Paulius

+1

तो क्या हम इसे प्रिंट नहीं कर सकते हैं और इसे फिर से नहीं कर सकते? – Barth

+0

मुझे लगता है कि हम कर सकते हैं, लेकिन जब मैं डिबगिंग कर रहा हूं - मुझे शायद ही कभी मुद्रित किया गया है - मैं आम तौर पर घड़ी विंडो में मूल्यों को देखता हूं (यदि मुझे आवश्यकता है)। – Paulius

6

मुख्य समारोह में प्रयास करें डीबगर से अपवाद छुपाता है। मैं कहूंगा, यह अच्छा नहीं है।

दूसरी ओर, ग्राहकों को डिबगर्स होने की उम्मीद नहीं है, इसलिए आकर्षक अपवाद अच्छा है। तो यह अच्छा है।

व्यक्तिगत रूप से, मैं रिलीज बिल्ड करते समय मुख्य कार्य में सभी अपवादों को पकड़ता हूं, और डीबग कॉन्फ़िगरेशन बनाते समय मैं ऐसा नहीं करता हूं।

0

सी ++ बाइबल i.e. स्ट्राउस्ट्रप पर एक नज़र डालें, उसके पास एक उदाहरण है जिसे एप्लाइड सी ++ प्रोग्रामिंग में भी दोहराया गया है। तर्क यह है:

int main(void) 
{ 
    try 
    { 
      // your code 
    } 
    catch (/* YourPossibleExceptions i.e. barfs you expect may occur */) 
    { 
    } 
    catch (...) // unexpected errors, so you can exit gracefully 
    { 
    } 
} 
+0

हां। लेकिन जैसा कि मैंने अपने जवाब में उल्लेख किया है - यह वास्तव में डीबगर की मदद नहीं करता है। यदि अपवाद पकड़ा नहीं गया है - डीबगर आपको स्रोत में सटीक स्थान दिखाएगा, जहां अपवाद फेंक दिया गया है। तो, यह केवल रिलीज बिल्ड में समझ में आता है। – Paulius

4

एक स्थिति का एक सरल उदाहरण है जहाँ स्टैक नहीं किया:
Why destructor is not called on exception?

स्थितियों की एक सूची जहां अपवाद आवेदन के बजाय समाप्त स्टैक को हो सकती है।
Why destructor is not called on exception?

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

परिणामस्वरूप मैं हमेशा मुख्य() में सभी अपवादों को पकड़ता हूं।

int main() 
{ 
    try 
    { 
    } 
    catch(std::exception const& e) 
    { /* LOG */ 
     // optimally rethrow 
    } 
    catch(...) // Catch anything else. 
    { /* LOG */ 
     // optimally rethrow 
    } 
} 

डीबगिंग के दौरान समस्याओं को पकड़ने में सहायता के लिए। Std :: अपवाद से अपने अपवाद प्राप्त करें और फिर std :: अपवाद के लिए निर्माता में ब्रेक पॉइंट चिपकाएं।

0

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

+1

क्या आप संभवतः विंडोज स्पेक से लिंक कर सकते हैं जहां यह कहता है? जो आपके उत्तर में कुछ अतिरिक्त संदर्भ/प्राधिकरण प्रदान करेगा। – jadarnel27

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

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