假设您在函数中有多个点可能导致相同的失败。哪种方法会更好?还有更好的选择吗?
{
...
if (some_failure_condition0) goto fail;
...
if (some_failure_condition1) goto fail;
...
if (some_failure_condition2) goto fail;
...
if (...) {
...
}
else if (...) {
...
}
else goto fail;
...
return;
fail:
/* handle error here */
...
}
或
{
auto fail = [] {
/* handle error here */
...
};
...
if (some_failure_condition0) fail();
...
if (some_failure_condition1) fail();
...
if (some_failure_condition2) fail();
...
if (...) {
...
}
else if (...) {
...
}
else fail();
...
}
答案 0 :(得分:1)
由于这是C ++而不是C,更好的选择是使用有助于保证正确调用析构函数的异常:
try
{
...
if (some_failure_condition0) throw fail;
...
if (some_failure_condition1) throw fail;
...
if (some_failure_condition2) throw fail;
...
if (...) {
...
}
else if (...) {
...
}
else throw fail;
...
return;
}
catch(const fail& f)
/* handle error here */
...
}
答案 1 :(得分:1)
一般来说,这完全取决于函数的语义。我通常会避免goto(我多年没有使用它),并且还避免使用返回码进行C风格的错误处理。对于错误处理,我遵守以下准则:
这使得像你的例子的代码在我生命中的大部分时间都已经过时了。
答案 2 :(得分:0)
这个怎么样?
#define MY_FAIL_CHECK(_condition) if(_condition) { throw some_exception; }
void foo()
{
MY_FAIL_CHECK(some_failure_condition0);
MY_FAIL_CHECK(some_failure_condition1);
MY_FAIL_CHECK(some_failure_condition2);
}
答案 3 :(得分:0)
如果您使用的是C ++,则没有合理的理由使用goto代替例外。
答案 4 :(得分:0)
我会创建子函数,如:
bool foo() // or enum or boost::optional
{
...
if (some_failure_condition0) return false;
...
if (some_failure_condition1) return false;
...
if (some_failure_condition2) return false;
...
if (...) {
...
}
else if (...) {
...
}
else return false;
...
return true;
}
void bar()
{
auto result = foo();
if (!result)
{
/* handle error here */
...
}
}
不要忘记使用RAII来避免一些可能是自动的处理。