2010-03-19 12 views
7

कुछ लेख समापन "कभी नहीं एक नाशक से एक अपवाद फेंक", और "std :: uncaught_exception() उपयोगी नहीं है" उदाहरण के लिए, कर रहे हैं:सही उपयोग

लेकिन ऐसा लगता है कि मैं बात नहीं मिल रहा है। तो मैंने एक छोटा परीक्षण उदाहरण लिखा (नीचे देखें)।

चूंकि सब कुछ परीक्षण उदाहरण के साथ ठीक है क्योंकि मैं इसके बारे में कुछ गलत कहने के बारे में कुछ टिप्पणियों की सराहना करता हूं?

परीक्षण के परिणामों:

./main

 
    Foo::~Foo(): caught exception - but have pending exception - ignoring 
    int main(int, char**): caught exception: from int Foo::bar(int) 

./main 1

 
    Foo::~Foo(): caught exception - but *no* exception is pending - rethrowing 
    int main(int, char**): caught exception: from Foo::~Foo() 

उदाहरण:

// file main.cpp 
// build with e.g. "make main" 
// tested successfully on Ubuntu-Karmic with g++ v4.4.1 
#include <iostream> 

class Foo { 
    public: 

    int bar(int i) { 
    if (0 == i) 
     throw(std::string("from ") + __PRETTY_FUNCTION__); 
    else 
     return i+1; 
    } 

    ~Foo() { 
    bool exc_pending=std::uncaught_exception(); 
    try { 
     bar(0); 
    } catch (const std::string &e) { 
     // ensure that no new exception has been created in the meantime 
     if (std::uncaught_exception()) exc_pending = true; 

     if (exc_pending) { 
     std::cerr << __PRETTY_FUNCTION__ 
        << ": caught exception - but have pending exception - ignoring" 
        << std::endl; 
     } else { 
     std::cerr << __PRETTY_FUNCTION__ 
        << ": caught exception - but *no* exception is pending - rethrowing" 
        << std::endl; 
     throw(std::string("from ") + __PRETTY_FUNCTION__); 
     } 
    } 
    } 

}; 

int main(int argc, char** argv) { 
    try { 
    Foo f; 
    // will throw an exception in Foo::bar() if no arguments given. Otherwise 
    // an exception from Foo::~Foo() is thrown. 
    f.bar(argc-1); 
    } catch (const std::string &e) { 
    std::cerr << __PRETTY_FUNCTION__ << ": caught exception: " << e << std::endl; 
    } 
    return 0; 
} 

जोड़ा : दूसरे शब्दों में: कुछ लेखों में चेतावनियों के बावजूद यह अपेक्षित काम करता है - तो इसमें क्या गलत हो सकता है?

+2

आपका प्रश्न क्या है? आप एक तंत्र के अपेक्षित व्यवहार को देख रहे हैं जिसका आपको उपयोग नहीं करना चाहिए। क्या आप परीक्षण/प्रयोग संदर्भ के बाहर इसका उपयोग करने पर विचार कर रहे हैं, और क्यों? – Potatoswatter

+0

@Potatoswatter: सवाल यह है: 'कुछ लेखों में चेतावनियों के बावजूद यह अपेक्षित काम करता है - तो इसके साथ क्या गलत हो सकता है?' –

+0

फेयर नफ, लेकिन यह आपके द्वारा जो कहा गया है उसे उद्धृत नहीं कर रहा है, और यह जानना असंभव है कि क्या अपेक्षित है, अधिक जानकारी के बिना अपने संदर्भ में उपयुक्त, या सुरक्षित। सुरक्षित मार्ग, जैसे हर्ब सटर और कई अन्य आपको बताएंगे, पहले स्थान पर विनाशक से फेंकना नहीं है। – Potatoswatter

उत्तर

5

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

यदि यह कभी कभी एक अपवाद फेंक नहीं होगा, तुम भी कभी नहीं एक अपवाद फेंक सकता है। इस तरह, आप कम से कम संगत हैं।

6

हर्ब सटर एक अलग मुद्दे का जिक्र कर रहा है। उन्होंने कहा कि के बारे में बात कर रहा है:

try 
{ 
} 
catch (...) 
{ 
    try 
    { 
     // here, std::uncaught_exception() will return true 
     // but it is still safe to throw an exception because 
     // we have opened a new try block 
    } 
    catch (...) 
    { 
    } 
} 

तो समस्या यह है कि अगर std::uncaught_exception() रिटर्न सच आप यकीन नहीं है कि आप सुरक्षित रूप से एक अपवाद है या नहीं फेंक सकता है के लिए पता नहीं है है। std::uncaught_exception() सुरक्षित होने के लिए सच होने पर आप अपवाद फेंकने से बचने के लिए समाप्त होते हैं।

+0

@ सैमुएल: '... एक अलग जारी करने का जिक्र है ... 'यही मैंने सोचा था। और - जब तक uncaught_exception() सत्य लौटाता है, तो मैं अपवाद नहीं फेंकता - क्या आपको विश्वास है कि मेरा दृष्टिकोण सुरक्षित है? –

+0

यह वास्तव में सही नहीं है। आपका अपवाद उस बिंदु पर पकड़ा गया है। आपको एक विनाशक में कोशिश/पकड़ रखना चाहिए था, जिसे अवांछित ढेर के दौरान बुलाया जाता है (सक्रिय अपवाद के कारण)। उस स्थिति में, एक अपवाद * सक्रिय रूप से स्टैक को अनदेखा कर रहा है, लेकिन आप फिर कोशिश/पकड़ ब्लॉक के अंदर हैं जहां आप * अपवाद फेंक सकते हैं। – dascandy

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