2016-02-19 54 views
-3

我有成功返回零一個功能,或者檢測到錯誤的行號:C++外部可見常量

int func() { 
    // stuff 
    if (something is wrong) { 
     return __LINE__; 
    } 
    // more stuff 
    if (something else is wrong) { 
     return __LINE__; 
    } 
    // all good 
    return 0; 
} 

真實呼叫者只檢查返回值是否爲零或不經常這樣:

int ret = func(); 
if (ret != 0) { 
    return ret; 
} 

然而,在測試中,我想檢查實際的返回值,以驗證某些故障條件被觸發:

int ret = func(); 
EXPECT_EQ(42, ret); 

這提出了一個問題,因爲當編輯func()的源文件時,返回語句的行以及返回的值也會改變。我希望行號值可用於func()的調用者。

是可能的「出口」行號這樣的:

// header 
extern const int line_number; 

// source 
const int line_number = __LINE__; 

不幸的是,這隻適用於功能的外線號碼。我想這樣的:

if (something is wrong) { 
    const int line_number = __LINE__; return __LINE__; 
    // or some other const thing 
} 

可以從另一個翻譯單位(文件)讀取。

我試過static const int line = __LINE__,但有兩個缺陷:

  • 它不是在頭宣佈的line_number定義。
  • 它可能不會被設置,直到執行通過它。
+1

C不是C++不是C!不要爲無關語言添加標籤。 – Olaf

+0

如果你需要返回代碼,返回一個'enum'值將是一個可能的解決方案,而不是行號。 – crashmstr

+1

爲什麼不用失敗類型的'enum'並返回失敗的'enum'值。這將從文件配置中分離錯誤報告。 – NathanOliver

回答

0

下面一個例子,我怎麼會輕易解決這個問題:

struct FuncErrorCodes { 
    enum Type { 
     OK = 0, 
     SOMETHING_IS_WRONG, 
     SOMETHING_ELSE_IS_WRONG, 
     ... 
    }; 
}; 

typedef FuncErrorCodes::Type FuncErrorCode; 

FuncErrorCode func() { 
    // stuff 
    if (something is wrong) { 
     return FuncErrorCodes::SOMETHING_IS_WRONG; 
    } 
    // more stuff 
    if (something else is wrong) { 
     return FuncErrorCodes::SOMETHING_ELSE_IS_WRONG; 
    } 
    ... 
    // all good 
    return FuncErrorCodes::OK; 
} 

我看不出有任何理由,我想用__LINE__錯誤代碼。

在通常情況下返回代碼仍然可以反對0測試(或更好,但FuncErrorCodes::OK)和我有沒有問題,測試的特定錯誤的原因,例如像:

FuncErrorCode rc = func(); 
EXPECT_EQ(FuncErrorCodes::SOMETHING_IS_WRONG, ret); 

編輯:請注意,即使您設法導出「設置爲錯誤代碼的最後一行」,它也不會以任何方式幫助您,因爲這將是函數返回的確切值(所以您已經知道它)。爲了實際工作,對於每個可能的錯誤行,您都需要使用單獨的變量,該變量將包含特定的行號(以便可以根據函數返回碼檢查是否發生特定錯誤)。

I.e.你會需要這樣的東西:

extern int something_wrong_line_number; 
extern int something_else_wrong_line_number; 

if (something is wrong) { 
    something_wrong_line_number = __LINE__; return __LINE__; 
} 

if (something else is wrong) { 
    something_else_wrong_line_number = __LINE__; return __LINE__; 
} 

// etc. - but it will of course still not work entirely well because the __LINE__ is only assigned if the error actually happens 

這是再爲每個特定的錯誤情況 - 只提供簡單的錯誤代碼,因爲我認爲沒有什麼不同(這要複雜得多)。