2010-03-09 12 views
11

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

if(! (data = (big_struct *) malloc(sizeof(*data)))){ 
    //report allocation error 
} else if(init_big_struct(data)){ 
    //handle initialization error 
} else ... 

की तरह कैसे तुम लोगों कोड के इस प्रकार लिख सकता हूँ की स्थिति में हो रहा है? मैंने कुछ स्टाइल गाइड की जांच की है, लेकिन वे परिवर्तनीय नामकरण और सफेद जगह से अधिक चिंतित हैं।

शैली मार्गदर्शिकाओं के लिए लिंक आपका स्वागत है।

संपादित करें: यदि यह स्पष्ट नहीं है, तो मैं इस शैली की सुगमता से असंतुष्ट हूं और कुछ बेहतर खोज रहा हूं।

+1

जब आप इसमें हों, तो मैं व्यक्तिगत रूप से '(big_struct *)' कास्ट छोड़ दूंगा जबतक कि आपको इस कोड को संकलित करने के लिए C++ कंपाइलर का उपयोग करने की आवश्यकता न हो। यह एक विवादित मुद्दा है, लेकिन यदि आपके पास कोई सी ++ आवश्यकता नहीं है तो मुझे लगता है कि इसे छोड़ना सबसे अच्छा है। –

उत्तर

15

हालांकि मुझे यह कहने में दर्द होता है, यह कभी भी लोकप्रिय goto के लिए एक मामला हो सकता है। यहां विषय पर एक लिंक दिया गया है: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/

+0

यदि आप अपने कोड में 'goto' देखने के प्रतिकूल हैं, तो आप हमेशा इसे छिपा सकते हैं। http://stackoverflow.com/questions/2314066/do-whilefalse – jschmier

+1

+1 गोटो का उपयोग करना अभी भी इस भयानक भाषा में सबसे अच्छा तरीका है। – Tronic

+1

हाँ - यह सी कोड के लिए अच्छा अभ्यास है (सी ++ कोड उपयोग अपवाद और आरएआईआई में)। संसाधन पीटीआरएस को न्यूल पर सेट करें; फिर सेट करें और एक सामान्य निकास बिंदु है जो जारी करता है अगर! केवल नकारात्मकता यह वास्तव में आपको कार्य के शीर्ष दायरे में अपने सभी संसाधन चर डाल देती है (मैं जितना संभव हो सके स्थानीय रूप से घोषित करना पसंद करता हूं) – pm100

13

मैं आमतौर पर इस तरह से है कि कोड लिखने:

data = (big_struct *) malloc(sizeof(*data)); 
if(!data){ 
    //report allocation error 
    return ...; 
} 

err = init_big_struct(data); 
if(err){ 
    //handle initialization error 
    return ...; 
} 

... 

इस तरह मैं अंदर अगर कार्यों बुला से बचने और डिबग आसान है क्योंकि आप वापसी मूल्यों की जाँच कर सकते हैं।

3

उत्पादन कोड में assert का उपयोग न करें।
डीबग मोड में, assert कुछ है कि वास्तव में हो सकता है के लिए प्रयोग नहीं करना चाहिए (जैसे malloc लौटने NULL), बल्कि यह असंभव मामलों में इस्तेमाल किया जाना चाहिए

Read this post for more.

(सरणी सूचकांक जैसे C में सीमा से बाहर है)
2

एक विधि जिस पर मैंने बहुत प्रभाव डाला था वह डब्ल्यू रिचर्ड स्टीवंस द्वारा Unix Network Programming में उपयोग किया गया था (कोड डाउनलोड करने योग्य here है। सामान्य कार्यों के लिए जो उन्हें हर समय सफल होने की उम्मीद है, और विफलता के लिए कोई सहारा नहीं है, वह उन्हें लपेटता है , एक पूंजी अक्षर (कोड को लंबवत संकुचित) का उपयोग करके:

void * Malloc(size_t size) { 
    void *ptr; 
    if ((ptr = malloc(size)) == NULL) 
     err_sys("malloc error"); 
    return(ptr); 
} 

err_sys यहां त्रुटि प्रदर्शित करता है और फिर exit(1) करता है। इस तरह आप बस मॉलोक को कॉल कर सकते हैं और जानते हैं कि कोई समस्या होने पर यह त्रुटि होगी।

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

+2

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

0

मैं

  • के प्रतिनिधि त्रुटि (स्टीवंस की तरह) कार्यों आवरण को
  • त्रुटि पर, longjmp का उपयोग करके अपवादों अनुकरण जाँच करते हैं। (मैं वास्तव में डेव हैन्सन के C Interfaces and Implementations का उपयोग अपवाद अनुकरण करने के लिए।)

एक अन्य विकल्प डॉन नुथ के literate programming त्रुटि हैंडलिंग कोड, या पूर्वप्रक्रमक के कुछ अन्य प्रकार के प्रबंधन के लिए उपयोग करने के लिए है।यह विकल्प तभी उपलब्ध होता है जब आप अपनी दुकान के लिए नियम निर्धारित करते हैं :-)

0

इस तरह के कोड की एकमात्र समूह संपत्ति यह है कि वहां केवल एक बाहरी रूप से लगाया गया अनुक्रम है जिसे इसे पालन करना है। यही कारण है कि आप इन आवंटन को एक समारोह में डालते हैं, लेकिन यह एक बहुत कमजोर समानता है। क्यों कुछ लोग मेरी समझ से परे है अगर नेस्टेड के दायरे के फायदे छोड़ने की सलाह देते हैं। आप प्रभावी ढंग से एक सुअर (लिपस्टिक का इरादा नहीं) पर लिपस्टिक डालने की कोशिश कर रहे हैं - कोड की प्रकृति कभी भी कुछ भी साफ नहीं करेगी, सबसे अच्छा आप कंपलर को पकड़ने (रखरखाव) त्रुटियों में मदद करने के लिए कर सकते हैं। आईएमएचओ के साथ चिपकाएं।

पीएस: अगर मैंने आपको अभी तक विश्वास नहीं किया है: गेटो-सॉल्यूशन कैसा दिखता है यदि आपको तीसरे निर्णय लेना है? अगर निश्चित रूप से उभरा हो जाएगा, लेकिन गोटो की ???

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