2012-10-04 31 views
8

我有自己的返回類型和函數這樣定義:一般規則:在錯誤代碼負值或正值C/C++

typedef enum xx_return_t { 
    success = 0, 
    general_error = -1, 
    specific_error = -2, 
    [...] 
} xx_return_type; 

xx_return_type generalFunction(void) { 
    if(there_was_an_error) 
     return general_error; 
} 

但是我在這裏的錯誤類型值有點不確定的; 什麼是C/C++中錯誤返回值的標準/最佳實踐 - 負面或正面

更新: 謝謝您的回答! 我一直在尋找關於C和C++的信息,但是我也意識到這對每種語言(異常,錯誤代碼,對象返回等)的一般結構和方法提出了很好的問題。

+0

您是否在問C或C++? – Default

回答

15

這實際上是兩個完全不同的問題(C和C++版本)僞裝成一個。

在C++中,答案很簡單:對...返回的數據值使用返回值,對錯誤/異常情況使用異常。不要在純C++中使用返回值進行錯誤檢查(C++ C++ API是另一回事)。

在C你沒有這個選項,所以我會建議使用0代表成功和負數的錯誤代碼。如果需要,這留下了靈活性,使用正數來獲得額外的成功信息(例如read調用)

+1

迄今爲止最好! {fill} –

+2

關於C++中的異常,我會注意到它並不意味着突然所有的方法都應該拋出。例如:'T const * MyMap :: find(std :: string const&name);'是一個方法,當名字找不到時不需要拋出;它可以只返回一個空指針。 –

+0

我同意Matthieu。只有在發生特殊事件時纔會拋出異常,而不是尋找普通的否定結果等。拋出異常比從函數返回值慢得多,即使它沒有拋出try {} catch()塊本身,並且包含所有異常處理機制也會使程序變慢。 – 4pie0

1

更好地使用0(零)和非零,因此它們也可以被視爲布爾值。通常,false是0,而其他則是true。

+0

這就是他在做什麼&非零可以是負面的和積極的... –

+1

@LuchianGrigore其實,他做的是相反的。正如你所提到的,兩者都很常見,但它也能夠使用真/假。 – Brady

+0

你說的是什麼? 「使用0和非零」而不是「使用非零和0」? –

4

C++:

  1. 這是一個選擇的問題,我已經看到了這兩者。
  2. 使用例外!
+4

「2.」特別適合這個'c'標籤;-) –

+4

(希望有'+ 0.5'選項;-)) –

+3

@ MichaelKrelin-hacker:C/C++問題始終存在問題。要麼是C,要麼是C++ ... –

2

我不知道關於C ...

...但在C++的想法是不使用的錯誤代碼,一般。

我並不是說你應該使用異常,但是錯誤代碼並不是真的太豐富(缺少上下文,當文件名未知時,FILE_NOT_FOUND的價值是什麼?)。

在我沒有使用異常的情況下,我傾向於更喜歡完整的錯誤對象。一個例子可能是:

boost::variant<File, Error> open(std::string const& filename, FileMode mode); 

你將得到一個文件或一個錯誤,取決於發生了什麼。

2

有幾個約定可供選擇:

  • 微軟使用0 = FALSE =錯誤大部分高層次的API的。並讓用戶使用全局函數查找特定錯誤GetLastError()
  • 微軟使用0 = ok表示較低級別的apis,如註冊表,音頻或電話。這些全部返回類似於HRESULT的類型,其中包含特定的錯誤代碼。
  • POSIX函數返回一個狀態通常返回-1爲錯誤,並讓用戶通過一個全局變量errno
  • 函數返回一個指針,通常爲錯誤返回NULL
  • C++ STL函數返回「結束」用於查找錯誤狀態如「未找到」。像'內存不足'這樣的錯誤會使用異常來發出信號。

一般來說,持續使用您的慣例比您使用的慣例更重要。

順便說一句,可以在微軟的頭文件中找到的怎麼不這樣做的一些例子:

#define S_OK  ((HRESULT)0x00000000L) 
#define S_FALSE ((HRESULT)0x00000001L) 

在Windows還提防兩種不同的誤差值的HANDLE的:0或INVALID_HANDLE_VALUE