2010-09-07 8 views
5

मेरे पास एक साधारण डिज़ाइन (?) प्रश्न है।सी: पैरामीटर जांच पर त्रुटि फेंक दें या इसे प्रशंसक को हिट करें?

मैं एक साधारण प्रोग्राम लिख रहा हूं, जिसमें कुछ ऐसे कार्य हैं जो इनके जैसा दिखते हैं।

float foo (float* m,size_t n){ 

    float result; 
    //do some calculations, for example a sum 


    return result/n; 
} 

मेरे पास कुछ पवित्र युद्ध खोलने के इरादे से इस पर कुछ प्रश्न हैं।

क्या मुझे n पर एक सैनिटी चेक जोड़ना चाहिए? यदि हां, तो मुझे कॉलर को कैसे जानना चाहिए?

रिटर्निंग -1 फ्लोट पर अजीब लग रहा है;

float foo(float *m,size_t n){ 
    if (n == 0) return -1f 

    ... 
    } 

मेरे अन्य विकल्प एक बाहर पैरामीटर

float foo(float *m,size_t n, int *error){ 

     if (n==0){ 
      *error = 1; 
      return 0f; 
     } 
     ... 
} 

अद्यतन

यह की तरह एक खिलौना कार्यक्रम है, बस कुछ सामान अभ्यास करने के लिए कोशिश कर रहा है। सवाल उस तथ्य से अधिक है। हो सकता है कि मुझे "ओओपी) अपवादों के बिना त्रुटियों को कैसे संभालना है" को फिर से लिखना चाहिए।

कॉल करने से पहले n परीक्षण करने पर भी विचार करें, लेकिन इसे उतना पसंद नहीं है।

कोई विचार? अग्रिम धन्यवाद।

+0

कार्यों के पर्यावरण के बारे में और अधिक सुनना उपयोगी हो सकता है। क्या वे स्थापित त्रुटि-जांच प्रथाओं के साथ कोड के एक समूह में मौजूद हैं, या जहां थर्ड-पार्टी कोड की कुछ अपेक्षाएं हैं? क्या यह एक स्टैंडअलोन खिलौना परियोजना है? – TSomKes

+1

@TsomKes ने मेरा प्रश्न अपडेट किया। – Tom

उत्तर

6

मुझे लगता है कि आपके out parameter विकल्प एक अच्छा है। लेकिन मुझे लगता है कि यह दूसरी तरफ बेहतर होगा। परिणाम प्राप्त करने के लिए आउट पैरामीटर का उपयोग करें और कॉल की स्थिति को दर्शाने के लिए वापसी मूल्य का उपयोग करें। इस

int foo(float *m, size_t n, float* result) 
{ 
    if(someFailureCondition) 
    return ERROR; // ERROR being an error integer 
    // else 
    // do some calculation 
    // set your result 
    return NO_ERROR; // NO_ERROR being an integer 
} 

संपादित की तरह: वापसी मान बाहर पैरामीटर की वर्तमान स्थिति को निरूपित करने के लिए और अधिक वर्बोज़ हो सकता है। जेम्सडलिन की टिप्पणी देखें!

+0

धन्यवाद, उस पर विचार नहीं किया। अधिक स्टाइलिश लगता है। – Tom

+1

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

2

यदि -1 फ़ंक्शन द्वारा वैसे भी वापस नहीं किया जाएगा, तो हर तरह से वापसी -1। लेकिन अगर पास = n = 0 फ़ंक्शन को तोड़ नहीं देगा, तो इसकी वास्तव में आवश्यकता नहीं है। मुझे लगता है कि एन सरणी एम का आकार है।

त्रुटियों को संभालना प्राथमिकता का विषय है। जब कोई फ़ंक्शन विफल रहता है तो ओपनजीएल त्रुटि कोड (-1 या अन्यथा) लौटकर त्रुटियों को संभालता है। त्रुटि कोड को GetLastError() (या ऐसा कुछ) पर througha कॉल लौटा दिया जाता है। यह एक आदर्श त्रुटि हैंडलिंग समाधान की तरह लगता है।

+0

हां, एन एम में तत्वों की संख्या है। – Tom

1

विशेष चल अंक मान आप उपयोग कर सकते हैं अगर आप चाहते हैं कर रहे हैं - उदाहरण के लिए, अपने फ्लोटिंग प्वाइंट कार्यान्वयन शांत Nans (नहीं एक नंबर) का समर्थन करता है तो आप math.h से NAN मैक्रो का उपयोग कर सकते हैं:

#include <math.h> 
float foo(float *m,size_t n) 
{ 
    if (n == 0) return NAN; 

    ... 
} 
+0

इसे माना जाता है, लेकिन क्या यह "कुछ भी नहीं" मामला नहीं है? – Tom

+0

मुझे यकीन नहीं है कि आपका क्या मतलब है। यह आपके '-1 एफ' मामले के समान होना चाहिए, सिवाय इसके कि आप इसके लिए' इस्नान() 'के साथ परीक्षण करते हैं, और यह बाद के फ्लोटिंग-पॉइंट कंप्यूटेशंस के माध्यम से प्रसारित होगा। – caf

1

आपको कॉलर्स को यह पता होना चाहिए कि आपके फ़ंक्शन के अर्थशास्त्र आपके कोड को स्पष्ट रूप से दस्तावेज कर रहे हैं।

आपके फ़ंक्शन का अनुबंध क्या है? यदि कॉलर्स को n के लिए 0 पास नहीं करना है, तो उसे समझाया जाना चाहिए, और फ़ंक्शन को assert का उपयोग यह सत्यापित करने के लिए करना चाहिए कि उन आवश्यकताओं को पूरा किया जाए।तार्किक त्रुटियों जल्दी पता लगाया जाना चाहिए, और उन विफलताओं को यथासंभव शानदार होना चाहिए।

अब

, आप एक पुस्तकालय है कि अन्य डेवलपर्स द्वारा भस्म हो जाएगा और चिंतित हैं कि लोगों assert विकलांग के साथ संकलित कर देगा के लिए कोड लिख रहे हैं, तो यह है कि गठबंधन करने के लिए एक नरम विफलता मोड कि हमेशा सक्षम है के साथ उचित है:

if (n == 0) 
{ 
    assert(0); 
    return NAN; /* Or return some error code */ 
} 
संबंधित मुद्दे