2016-02-19 68 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 

这是再为每个特定的错误情况 - 只提供简单的错误代码,因为我认为没有什么不同(这要复杂得多)。