5

तो मैं कुछ कोड लिख रहा था और मैंने देखा कि वाक्य रचनात्मक, प्रकार, और अन्य संकलन-समय त्रुटियों के अलावा, सी ++ कोई अन्य अपवाद नहीं फेंकता है। इसलिए मैं यह एक बहुत ही तुच्छ कार्यक्रम के साथ बाहर परीक्षण करने का फैसला:सी ++ अपवाद हैंडलिंग

#include<iostream> 

int main() { 
    std::count<<5/0<<std::endl; 
return 1 
} 

जब मैंने इसे जी ++ का उपयोग कर संकलित, जी ++ मुझे एक चेतावनी कह रहा 0. से विभाजित किया गया था लेकिन यह अभी भी कोड संकलित दे दी है। फिर जब मैंने इसे चलाया, तो उसने कुछ वास्तव में बड़ी मनमानी संख्या मुद्रित की। जब मैं जानना चाहता हूं, सी ++ अपवादों के साथ कैसे व्यवहार करता है? 0 द्वारा इंटीजर डिवीजन एक बहुत ही छोटा उदाहरण होना चाहिए जब एक अपवाद फेंक दिया जाना चाहिए और कार्यक्रम को समाप्त करना चाहिए।

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

उत्तर

8

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

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

यह सी ++ भाषाओं की तुलना में अधिक शक्तिशाली बनाता है जो हमेशा जांच करता है (जैसे जावा या पायथन) क्योंकि जब आप चेक करना चाहते हैं तो आप चुन सकते हैं, और जब आप नहीं करते हैं। (दूसरी ओर, यह जावा या पायथन से सी ++ कम सुरक्षित बनाता है। यह एक व्यापार बंद है)।


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

+0

धन्यवाद जो समझ में आता है। तो एक और सवाल है। यदि std :: cout का उपयोग करने के बजाय, मैं std :: cerr का उपयोग करता हूं, तो क्या यह अपवाद फेंक देगा, या सिर्फ त्रुटि स्ट्रीम पर प्रिंट करेगा? और अगर मैं अपना अपवाद बना देता हूं (चलो कहें foo) और मेरे कोड में मैं फेंक फू कहता हूं, क्या मेरा प्रोग्राम तुरंत मारेगा और foo.what() मुद्रित किया जाएगा? या क्या मुझे ऐसा करने के लिए स्पष्ट रूप से सी ++ बताना होगा? – user1413793

+0

@ user1413793: यदि आप 'std :: cerr' पर लिखते हैं, तो यह केवल त्रुटि स्ट्रीम पर प्रिंट होगा। आप कमांड लाइन ('>' बनाम '2>') पर पुनर्निर्देशन के माध्यम से आउटपुट स्ट्रीम और त्रुटि स्ट्रीम को विभिन्न स्थानों पर भेज सकते हैं। यदि आप एक अपवाद फेंकते हैं, और आप इसे कहीं भी नहीं पकड़ते हैं, तो प्रोग्राम तुरंत समाप्त हो जाएगा और एक त्रुटि संदेश प्रिंट करेगा। (अधिक सटीक रूप से, 'std :: terminate' नामक फ़ंक्शन को कॉल किया जाएगा, जिसका डिफ़ॉल्ट व्यवहार प्रोग्राम को समाप्त करना और अपवाद के संदेश को प्रिंट करना है। आप' std :: set_terminate 'को कॉल करके व्यवहार को ओवरराइड कर सकते हैं। उनको देखो 'रुचि रखते हैं।) – HighCommander4

0

दृश्य सी ++ सही ढंग से शून्य त्रुटि से विभाजित के रूप में इसे ध्वजांकित करता है। तो अगर यह संकलित नहीं होता है, तो इसे चलाने का कोई सवाल नहीं है।

+0

का जवाब लेकिन मानक के अनुसार यह 'सही' है करने के लिए? बस उत्सुक। –

+0

शून्य से विभाजित किसी भी मानक से पहले भी अपरिभाषित है, है ना? – Superman

3

हां, रनटाइम अपवाद हैं। एक उदाहरण out_of_range है, जिसे vector::at द्वारा फेंक दिया गया है।

हालांकि, शून्य से भाग अपरिभाषित है (C++ 0x §5.6/4):

हैं/या% की दूसरी संकार्य शून्य व्यवहार unde फाई नेड जाता है।

तो यह संकलित करने में विफल हो सकता है, एक अपवाद अपवाद फेंक सकता है, "कुछ वास्तव में बड़ी मनमानी संख्या" या segfault प्रिंट कर सकता है।

+0

ठीक है धन्यवाद! मैं बस उलझन में था क्योंकि अन्य भाषाएं अपवाद फेंकती हैं लेकिन यह समझ में आता है :) – user1413793

2

सी ++ केवल मानक अपवाद फेंकता है जो सी ++ मानक में अच्छी तरह परिभाषित हैं।

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

सबसे अच्छा आप त्रुटि स्थिति (divisor शून्य के बराबर) जांचने के लिए कर सकते हैं और ऐसे मामलों में स्पष्ट रूप से अपवाद फेंक सकते हैं।

संपादित करें: टिप्पणी

class A 
{ 
    public: 
     void f() 
     { 
      int x; 
      //For illustration only 
      int a = 0; 
      if(a == 0) 
        throw std::runtime_error("Divide by zero Exception"); 
      x=1/a; 
     } 

     A() 
     { 
       try 
       { 
        f(); 
       } 
       catch(const std::runtime_error& e) 
       { 
        cout << "Exception caught\n"; 
        cout << e.what(); 
       } 
     } 
};  
+0

अपवाद फेंकने के कारण प्रोग्राम को समाप्त कर दिया जाएगा और अपवाद मुद्रित किया जाएगा, या फिर मुझे अपवाद पकड़ना होगा और स्पष्ट रूप से सी ++ को क्या कहना है? – user1413793

+1

@ user1413793: उत्तर अपडेट किया गया। आपको अपवाद पकड़ना होगा और तय करना होगा कि इसके बारे में क्या करना है। –

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