2010-09-21 12 views
25

मेरे पास कुछ सी कोड है जिसके साथ मैं काम कर रहा हूं, और जब कोड चल रहा है तो मुझे त्रुटियां मिल रही हैं लेकिन उचित प्रयास/पकड़ (सी # या सी ++ में) के बारे में कम जानकारी है।एएनएसआई सी कोशिश/पकड़ के बराबर?

सी में उदाहरण के लिए ++ मैं बस करना चाहते हैं:

try{ 
//some stuff 
} 
catch(...) 
{ 
//handle error 
} 

लेकिन एएनएसआई सी में मैं थोड़ा खो रहा हूँ। मैंने कुछ ऑनलाइन खोजों की कोशिश की लेकिन मुझे यह समझने/समझने के बारे में पर्याप्त जानकारी नहीं दिखाई दे रही है कि अगर कोई मुझे सही दिशा में इंगित कर सकता है तो मैं यहां पूछूंगा।

यहां कोड है जिसके साथ मैं काम कर रहा हूं (काफी सरल, पुनरावर्ती विधि) और कोशिश/पकड़ (या समकक्ष त्रुटि-संचालन संरचना) के साथ लपेटना चाहूंगा।

हालांकि मेरा मुख्य प्रश्न यह है कि एएनएसआई सी में कोशिश/पकड़ कैसे करें ... कार्यान्वयन/उदाहरण को रिकर्सिव नहीं होना चाहिए।

void getInfo(int offset, myfile::MyItem * item) 
{ 
    ll::String myOtherInfo = item->getOtherInfo(); 
    if(myOtherInfo.isNull()) 
     myOtherInfo = ""; 
    ll::String getOne = ""; 
    myfile::Abc * abc = item->getOrig(); 
    if(abc != NULL) 
    { 
     getOne = abc->getOne(); 
    } 
    for(int i = 0 ; i < offset ; i++) 
    { 
      printf("found: %d", i); 
    } 
    if(abc != NULL) 
     abc->release(); 
    int childCount = item->getChildCount(); 
    offset++; 
    for(int i = 0 ; i < childCount ; i++) 
     getInfo(offset, item->getChild(i)); 
    item->release(); 
} 
+2

http://www.nicemice.net/cexcept/ कुछ उपयोगी हो सकता है – anijhaw

+23

यह कोड सी, ansi या अन्यथा नहीं है। सी में '::' स्कोप ऑपरेटर नहीं है। –

+4

सी में तंत्र को संभालने के अपवाद नहीं हैं। सभी त्रुटि हैंडलिंग आमतौर पर रिटर्न वैल्यू और इरनम वैरिएबल के साथ की जाती है। बीटीडब्ल्यू, कुछ विस्तृत विशेषज्ञ टिप्पणियां प्राप्त करना अच्छा होगा कि कैसे सी में हैंडलिंग ठीक से किया जाता है :) – Kel

उत्तर

25

आम तौर पर, आप नहीं करते हैं।

यह setjmp और longjmp उपयोग करने के लिए काफी प्रयास करने के लिए कुछ इसी तरह/कैच निर्माण करने के लिए संभव है, यद्यपि वहाँ विनाशकर्ता के रूप में सी में ऐसी कोई बात है या तनाव मुक्त होने के ढेर है, तो आरए II सवाल से बाहर है। आप एक तथाकथित "क्लीनअप स्टैक" के साथ आरएआईआई का अनुमान लगा सकते हैं (उदाहरण के लिए सिम्बियन/सी ++ देखें), हालांकि यह बहुत करीब अनुमान नहीं है, और यह बहुत काम है।

सी में त्रुटियों या विफलता को इंगित करने का सामान्य तरीका सफलता की स्थिति को इंगित करने वाला मान वापस करना है। कॉलर्स वापसी मूल्य की जांच करते हैं और तदनुसार कार्य करते हैं। उदाहरण के लिए मानक सी फ़ंक्शन: printf, read, open, विचारों के लिए अपने कार्यों को निर्दिष्ट करने के लिए देखें।

सी और सी ++ कोड मिश्रण करते समय, आपको यह सुनिश्चित करना होगा कि एक सी ++ अपवाद कभी भी सी कोड तक नहीं पहुंचता। सी ++ कार्यों को लिखते समय जिन्हें सी से बुलाया जाएगा, सबकुछ पकड़ लें।

+19

आईएमई सी में त्रुटियों या विफलता को इंगित करने का सामान्य तरीका कॉलर द्वारा अनदेखा किया गया मान वापस करना है। ': (' – sbi

+2

@ एसबीआई: आईएमई, कुछ लोग अभी भी मानते हैं कि "एक मूल्य वापस करें" सी ++, जावा और सी # में जाने का तरीका है ... ': (' – paercebal

+0

@paercebal: मुझे पता है। ':(' – sbi

1

यदि आप एकाधिक स्तर की कूद करना चाहते हैं, तो setjmp() और longjmp() देखें। वे एक आदिम अपवाद फेंक के रूप में इस्तेमाल किया जा सकता है। setjmp() फ़ंक्शन एक रिटर्न-टू-प्ले स्थान सेट करता है, और स्थिति मान देता है। longjmp() फ़ंक्शन वापसी-स्थान पर जाता है, और स्थिति मान प्रदान करता है। आप स्थिति मूल्य के आधार पर setjmp() के बाद कॉल किए जाने पर catch फ़ंक्शन बना सकते हैं।

किसी भी कारण से, C++ में उनका उपयोग न करें। वे अनावश्यक या कॉल विनाशकों को ढेर नहीं करते हैं।

17

सी अपवाद हैंडलिंग का समर्थन नहीं करता है।

इस समस्या के लिए एक दृष्टिकोण पर जानकारी here है। यह सरल setjmp/longjmp दृष्टिकोण दिखाता है लेकिन गहराई से ढंका एक अधिक परिष्कृत विकल्प भी प्रदान करता है।

+0

हम्म, तीसरा डाउनवोट आज। इस के लिए कोई विशेष कारण? मैंने सोचा कि यह आशाजनक लग रहा है। –

+0

क्या कोई आपको प्राप्त करने के लिए बाहर है? –

+2

+1 क्योंकि नीचे वोट गलत था ... प्रश्न के लिए सही लिंक – Hogan

0

चूंकि सी ++ मूल रूप से सी प्री-प्रोसेसर के रूप में कार्यान्वित किया गया था और इसमें कोशिश/पकड़ था कि आप बजेर्न स्ट्रॉस्ट्रप के काम को फिर से कर सकते हैं और ऐसा करने के लिए एक प्री-प्रोसेसर लिख सकते हैं।

FILE *if = fopen(...); 
FILE *of = NULL; 
if (if == NULL) return; 

of = fopen(...); 
if (of == NULL) goto close_if; 

/* ...code... */ 
if (something_is_wrong) goto close_of; 

/* ... other code... */ 

close_of: 
    fclose(of); 
close_if: 
    fclose(if); 

return state; 

वैकल्पिक रूप से आप इसे नकली एक और समारोह

int try_code(type *var_we_must_write, othertype var_we_only_read /*, ... */){ 
    /* ...code... */ 
    if (!some_condition) return 1; 
    /* ...code... */ 
    if (!another_condition) return 2; 
    /* ...code... */ 
    if (last_way_to_fail) return 4; 
    return 0; 
} 

void calling_routine(){ 
    /* ... */ 
    if (try_code(&x,y/*, other state */)) { 
    /* do your finally here */ 
    } 
/* ... */ 
} 

में "कोशिश" कोड अलग से एक सीमित रास्ते में लेकिन न तो दृष्टिकोण है कर सकते हैं:

+1

सी ++ के समय अपवादों को पेश किया गया था, सी-प्रीप्रोसेसर कार्यान्वयन एक इतिहास था। –

+0

@ नीमनजा: यह वास्तव में मूल के लिए सच है सीफ्रंट। [कॉमौ सी ++] (http://www.comeaucomputing.com), हालांकि, अभी भी सी कोड आउटपुट करता है। (क्योंकि यह उच्च पोर्टेबिलिटी के लिए बनाता है।) लेकिन मुझे संदेह है कि यह अब किसी अन्य कंपाइलर के असेंबलर आउटपुट से उपयोगी है : यह मशीन से उत्पन्न कोड है, और मानव उपभोग के लिए नहीं। – sbi

+1

मेरा मानना ​​है कि अपवाद ऐसे स्ट्रॉ थे जो ऊंट की पीठ तोड़ते थे, जहां ऊंट सीएफ + कंपाइलर था। Stroupstrup "सी ++ के डिजाइन और विकास" देखें। –

4

क्लासिक तनाव मुक्त होने के goto रों पैटर्न नहीं है पूरी तरह से समकक्ष। आप आप स्वत: रोलबैक नहीं मिलता है जब तक कोई हैंडलर पाया जाता है, सभी संसाधनों का प्रबंधन स्वयं करने के लिए है, और इतने पर ...

+0

ईक!यह वास्तव में मेरे लिए गन्दा लग रहा है। मैं नीचे दी गई मेरी विधि पसंद करता हूं। गोटो के लिए कोई ज़रूरत नहीं! – James

+0

'गोटो' सी में जाने के लिए रास्ता है (पन क्षमा करें) सी से बाहर निकलने वाले लेबल होने पर, ओवरकिल की तरह लगता है। यह एक क्लीनर (हालांकि यदि आवश्यक हो) के लिए क्लीनर (हालांकि थोड़ा कम कुशल) है, यह जांचने के लिए कि कौन से संसाधन आवंटित किए गए थे। – jamesdlin

+0

@jamesdlin: एकाधिक लेबल आपको कुछ विशिष्ट खरीदते हैं: प्रत्येक एक ऐसे संसाधन से मेल खाता है जिसे रिलीज़ करने की आवश्यकता हो सकती है। आप रिलीज पर सशर्त के साथ उनसे बच सकते हैं लेकिन कुछ मामलों में (यह एक नहीं) जो अतिरिक्त झंडे के लिए कॉल करता है। जहां तक ​​मैं कह सकता हूं स्वाद का मामला। – dmckee

2

इस पुस्तक में longjmp के साथ एक संभव कार्यान्वयन पा सकते हैं: C Interfaces and Implementations: Techniques for Creating Reusable Software - David Hanson

और आप पुस्तक में उपयोग की जाने वाली शैली के उदाहरण के रूप में here और here कोड पा सकते हैं।

4

एक उपयोगी कोडिंग शैली जिसे मैं उपयोग करना चाहता हूं वह निम्न है। मुझे नहीं पता कि इसका कोई विशेष नाम है या नहीं, लेकिन जब मैं रिवर्स इंजीनियरिंग समकक्ष सी कोड में कुछ असेंबली कोड रिवर्स इंजीनियरिंग था, तो मैं इसे पार कर गया। आप इंडेंटेशन लेवल खो देते हैं लेकिन यह मेरे लिए इतना बड़ा सौदा नहीं है। समीक्षक के लिए देखें जो अनंत लूप को इंगित करेगा! exceptions4c: :)

int SomeFunction() { 
    int err = SUCCESS; 

    do { 
     err = DoSomethingThatMayFail(); 
     if (err != SUCCESS) { 
      printf("DoSomethingThatMayFail() failed with %d", err); 
      break; 
     } 

     err = DoSomethingElse(); 
     if (err != SUCCESS) { 
      printf("DoSomethingElse() failed with %d", err); 
      break; 
     } 

     // ... call as many functions as needed. 

     // If execution gets there everything succeeded! 
     return SUCCESS; 
    while (false); 

    // Something went wrong! 
    // Close handles or free memory that may have been allocated successfully. 

    return err; 
} 
+1

अच्छा। यदि आपको सशर्त रूप से सामानों को खोलने की आवश्यकता है तो आपको घोंसले के उदाहरणों की आवश्यकता हो सकती है। – dmckee

4

यह सी में एक अपवाद हैंडलिंग प्रणाली के अपने कार्यान्वयन है।

यह मैक्रो के द्वारा संचालित है, setjmp और longjmp की चोटी पर बनाया गया है और यह 100% पोर्टेबल एएनएसआई सी

There आप भी सभी विभिन्न कार्यान्वयन मैं के बारे में पता की एक सूची प्राप्त कर सकते हैं।

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