2009-09-04 13 views
8

मेरे पास कुछ सी ++ कोड है जो एक बहुत ही मानक अपवाद पैटर्न का उपयोग करता है:मेरे सी ++ अपवाद क्यों नहीं पकड़े जा रहे हैं?

try { 
    // some code that throws a std::exception 
} 
catch (std::exception &e) { 
    // handle the exception 
} 

समस्या यह है कि अपवाद नहीं पकड़े जा रहे हैं और मैं यह नहीं समझ सकता कि क्यों।

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

मैं एक साधारण उदाहरण बनाने में सक्षम नहीं हूं जो इस व्यवहार को एक साधारण उदाहरण में पुन: उत्पन्न करता है। जब मैं अपने बड़े कार्यक्रम के संदर्भ से प्रासंगिक कोड लेता हूं तो सब कुछ काम करता है।

क्या कोई सुझाव दे सकता है कि मेरे अपवाद क्यों नहीं पकड़े जा रहे हैं?

+1

आपको यह सोचने के लिए क्या सबूत हैं कि एक अपवाद फेंक दिया जा रहा है? आपके पास क्या सबूत हैं कि यह 'std :: अपवाद 'से निकला है? (यह नहीं कह रहा कि आप गलत हैं, लेकिन यहां जानकारी की एक अलग कमी है) –

उत्तर

-2

सभी से इनपुट के लिए धन्यवाद। वे किसी भी व्यक्ति के लिए अच्छे सुझाव हैं जो एक समान समस्या में भाग लेते हैं। यह अब काम कर रहा है, लेकिन मुझे 100% यकीन नहीं है कि मैंने किए गए विभिन्न परिवर्तनों में से चीजें फिर से बनने लगीं। एक बार फिर, काम करने और वहां से बैक अप बनाने के लिए सरल बनाने का दृष्टिकोण।

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

15

catch(...) {} ब्लॉक आज़माएं, देखें कि एक अपवाद वास्तव में फेंक दिया गया है या नहीं।

+0

मुझे यह जवाब नहीं समझा - प्रश्न में पहले से ही एक कैच() ब्लॉक शामिल है। –

+3

प्रश्न में 'std :: अपवाद' प्रकार के अपवादों के लिए एक हैंडलर शामिल है। एक इलिप्सिस (...) का उपयोग करके एक कैच ब्लॉक किसी भी अपवाद को पकड़ लेगा, इससे कोई फर्क नहीं पड़ता कि फेंक अपवाद का प्रकार क्या है। एक "डिफ़ॉल्ट" हैंडलर की तरह। –

3

मैं दो सिद्धांतों की पेशकश कर सकते:

  1. अपवाद पकड़ा जाता है इससे पहले कि यह अपनी पकड़ खंड आता है; ढेर पर कोई भी कार्य अपराधी हो सकता है। जैसा कि माइकल का प्रस्ताव है, सबकुछ पकड़ने का प्रयास करें।
  2. अपवाद अनचाहे आपके हैंडलर को ढूंढने में विफल रहता है। इसे अधिक विस्तार से विश्लेषण करने के लिए, आपको अपवाद कोड को अपवाद करना होगा, जो बहुत बालों वाली है। देखें कि -fobjc-exceptions के साथ उद्देश्य-सी कोड संकलित करने में मदद करता है या नहीं।
1

यह एक लंबा शॉट हो सकता है, लेकिन विजुअल स्टूडियो की कंपाइलर सेटिंग्स में पूरी तरह अपवादों को बंद करने का विकल्प होता है। शायद जीसीसी/एक्सकोड में कुछ ऐसा ही है।

0

सी ++ अपवाद कुछ भी हो सकता है, अक्सर char*catch (...) जोड़ने से पहले सुझाव दिया गया है कि कम से कम इसे तोड़ने के लिए और देखें कि क्या हो रहा है।

+2

मैंने कभी भी 'char *' अपवाद नहीं देखा है और जो भी –

7

मुझे लगता है कि ऑब्जेक्टिव-सी और सी ++ के बीच परस्पर क्रिया दोषी है, लेकिन मेरा यह सब नीचे पिन करने के लिए प्रयास विफल रहे हैं।

आप शायद सही हैं, हालांकि इसे ट्रैक करना मुश्किल है।

पहले, जीसीसी स्पष्ट does not allow you to throw exceptions in Objective C++ and catch them in C++ ("जब ऑब्जेक्टिव-सी ++ से इस्तेमाल किया, ऑब्जेक्टिव-सी अपवाद मॉडल इस समय सी ++ अपवाद के साथ interoperate नहीं है। इसका मतलब है आप नहीं कर सकते हैं @throw ऑब्जेक्टिव-सी से एक अपवाद है और यह catch C++ , या इसके विपरीत (यानी, throw ... @catch)। ")

हालांकि, मुझे लगता है कि आप एक मामले में जहां उद्देश्य सी ++ कॉल सी ++ कोड का वर्णन कर रहे हैं, सी ++ कोड फेंकता है और आप के लिए सी ++ कोड के लिए उम्मीद कर रहे हैं अपवाद पकड़ो। दुर्भाग्यवश मुझे इस विशिष्ट मामले के लिए दस्तावेज़ीकरण खोजने में कठिनाई हो रही है। कुछ उम्मीद है क्योंकि, "It is believed to be safe to throw a C++ exception from one file through another file compiled for the Java exception model, or vice versa, but there may be bugs in this area।" यदि वे जावा के लिए ऐसा कर सकते हैं, तो वे उद्देश्य सी ++ के लिए ऐसा कर सकते हैं।

कम से कम, आपको संकलन समय पर -fexceptions निर्दिष्ट करने की आवश्यकता होगी ("सी कोड को संकलित करते समय आपको इस विकल्प को सक्षम करने की आवश्यकता हो सकती है जिसे सी ++ में लिखे गए अपवाद हैंडलर के साथ ठीक से इंटरऑपरेट करने की आवश्यकता है")।फिर, यह विशेष रूप से उद्देश्य सी ++ का उल्लेख नहीं करता है लेकिन यह लागू हो सकता है।

5

अपवाद के साथ एक छोटा ज्ञात गोचा बेस क्लास की पहुंच से संबंधित है।

यदि आप वास्तव में std::exception से निजी रूप से प्राप्त कक्षा को फेंक रहे हैं तो std::exception हैंडलर नहीं चुना जाएगा।

उदाहरण के लिए

:

#include <iostream> 

class A { }; 
class B : private A { } ; 

int main() 
{ 
    try 
    { 
    throw B(); 
    } 
    catch (A &) 
    { 
    std::cout << "Caught an 'A'" << std::endl; 
    } 
    catch (B &) 
    { 
    std::cout << "Caught an 'B'" << std::endl; 
    } 
} 

आमतौर पर, संचालकों 'बी' हैंडलर में परिणाम होगा की तरह के एक आदेश का चयन किया जा रहा है कभी नहीं, लेकिन इस मामले से 'बी' dervies 'ए' निजी तौर पर और इतने में प्रकार 'ए' के ​​लिए कैच हैंडलर पर विचार नहीं किया जाता है।

16

C++ allows you a variety of options for catching: value, reference or pointer. ध्यान दें कि यह कोड केवल std :: अपवाद संदर्भ या मूल्य द्वारा पारित पकड़ता:

try { 
    // some code that throws a std::exception 
} 
catch (std::exception &e) { 
    // handle the exception 
} 

यह संभावना है कि अपवाद सूचक द्वारा पारित किया जा रहा है है:

catch (std::exception* e) 

चेक कोड वह अपवाद फेंक रहा है, और देखें कि यह कैसे कर रहा है।

जैसा कि मार्क इंगित करता है, यदि आप संदर्भ के बजाय मूल्य से पकड़ते हैं तो आप अपनी वस्तु को टुकड़ा करने का जोखिम उठाते हैं।

+0

का उपयोग करता है उसे थप्पड़ मारता है - यह सिर्फ मेरी समस्या को ठीक करता है। –

+0

इसे सुनकर खुशी हुई, बेन एल! – Bill

+0

यह उत्तर जावा/स्क्रिप्टिंग भाषाओं की पृष्ठभूमि से आने वाला एक अच्छा खोज था, एक स्वाभाविक रूप से मानता है कि अपवाद हमेशा मूल्य से पारित होते हैं। धन्यवाद। – Cray

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