如何重构这个GOTO(不涉及资源释放)?

时间:2011-11-07 19:41:10

标签: optimization coding-style conditional goto control-flow

这是一个简单的控制流GOTO问题,与资源分配无关。

有两个级别的检查是否一段数据是好​​的"。如果且仅当通过第一次检查时,我们会进行第二次检查。如果数据未通过测试,我们会使用默认值。

第二项检查涉及中间数据的几个步骤,因此我们无法将其置于短路||状态。此外,如果第二次测试通过,我们使用第二次测试的输出而不是原始数据。

这是实时处理情况下的内循环,因此效率非常重要。我们不想多次进行任何计算。

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
    }
    else {
        goto FAIL;
    }
}
else {
FAIL:
    use_result(DEFAULT_VALUE);
}

这个GOTO似乎以最高的效率满足了我的所有要求。我可以想到其他一些方法,但所有这些都涉及额外的存储或条件。我对GOTO很谨慎。事实上,如果我使用它,这将是我第一次使用GOTO。所以,请帮我找到出路!

3 个答案:

答案 0 :(得分:1)

我们可以在没有太多工作的情况下解决这个问题,但是以这种方式使用goto并不一定是坏行为 - 例如linux内核使用这个约定只在一个地方进行错误处理,我认为代码很清楚。

使用异常来解决这个问题显然是一种解决方案,但这确实会在错误情况下降低性能,因此我认为这是不可能的。

所以,如果你愿意,这应该没问题:

if (firstCheck(data) && secondCheck(result = analyze(data)) {
    use_result(result);
}
else {
    // fail
}

答案 1 :(得分:1)

使用continue转到下一个循环迭代

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
        continue;
    }
}
use_result(DEFAULT_VALUE);

答案 2 :(得分:0)

你不只是使用goto。您正在使用进入另一个范围的goto。更简单:

if (firstCheck(data)) {
    result = analyze(data);
    use_result (secondCheck (result) ? result : DEFAULT_VALUE);
}
else {
    use_result(DEFAULT_VALUE);
}

清洁,没有代码重复,可扩展:

int result = DEFAULT_VALUE;
if (firstCheck(data)) {
    int tmpResult = analyze(data);
    if (secondCheck (tmpResult))
        result = tmpResult;
}
use_result (result);