我们的代码(在一个简单的库实现中)开始看起来像这样:
err = callToUnderlyingLibrary1();
if (err!=0) {
printf ("blah %d\n", err);
...
}
err = callToUnderlyingLibrary2();
if (err!=0) {
printf ("blah %d\n", err);
...
}
err = callToUnderlyingLibrary3();
if (err!=0) {
printf ("blah %d\n", err);
...
}
Run Code Online (Sandbox Code Playgroud)
这很麻烦,很丑陋.有一个更好的方法吗 ?也许使用C预处理器?我想的是:
CHECK callToUnderlyingLibrary1();
CHECK callToUnderlyingLibrary2();
CHECK callToUnderlyingLibrary3();
Run Code Online (Sandbox Code Playgroud)
CHECK宏调用函数并进行基本错误检查.
是否有首选的惯用方法来处理这个问题?
Ale*_* C. 16
通常,在C中,一个goto用于错误处理:
int foo()
{
if (Function1() == ERROR_CODE) goto error;
...
struct bar *x = acquire_structure;
...
if (Function2() == ERROR_CODE) goto error0;
...
release_structure(x);
return 0;
error0:
release_structure(x);
error:
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这可以通过宏和更聪明的指令流来改进(以避免重复清理代码),但我希望你明白这一点.
flu*_*ffy 14
另一种基于宏的方法,您可以使用它来轻松地缓解C中的缺点:
#define CHECK(x) do { \
int retval = (x); \
if (retval != 0) { \
fprintf(stderr, "Runtime error: %s returned %d at %s:%d", #x, retval, __FILE__, __LINE__); \
return /* or throw or whatever */; \
} \
} while (0)
Run Code Online (Sandbox Code Playgroud)
然后调用它你有:
CHECK(doSomething1());
CHECK(doSomething2());
// etc.
Run Code Online (Sandbox Code Playgroud)
对于奖励积分,您可以轻松扩展CHECK宏以获取第二个参数y,即失败时该怎么做:
#define CHECK(x, y) do { \
int retval = (x); \
if (retval != 0) { \
fprintf(stderr, "Runtime error: %s returned %d at %s:%d", #x, retval, __FILE__, __LINE__); \
y; \
} \
} while (0)
// We're returning a different error code
CHECK(someFunction1(foo), return someErrorCode);
// We're actually calling it from C++ and can throw an exception
CHECK(someFunction2(foo), throw SomeException("someFunction2 failed")):
Run Code Online (Sandbox Code Playgroud)
我认为你应该看看异常和异常处理.http://www.cplusplus.com/doc/tutorial/exceptions/
try{
callToUnderlyingLibrary1();
callToUnderlyingLibrary2();
callToUnderlyingLibrary3();
}catch(exception& e)
//Handle exception
}
Run Code Online (Sandbox Code Playgroud)
如果出现错误,您的库函数可能会抛出异常