c++ - 函数怎么写才整齐?考虑日志,一次返回,不再缩进?

标签 c++ logging return goto

<分区>

有一个函数 Foo。 Foo 首先调用 Bar(),然后是一些语句,然后是 Walk(),然后是一些语句,然后是 Run(),然后是一些语句,然后是 Fly(),然后是一些语句。

此外,我不允许在我的代码中使用异常。因为我公司的代码标准。 :(

有几种方法,我可以编写 Foo(),如下所示。有些干净但不安全;有些真的很难看,但记录了所有日志。我真的很困惑。

哪个最好,你有更好的主意吗?

谁能帮帮我?

我从五个方向思考过这个问题:(clean[没有不必要的缩进]), (one return), (no goto), (print log), (check return value)。但我仍然很困惑。 goto真的有问题吗?是否需要记录所有内容?

图1 优点:干净。 缺点:没有日志并且不检查返回值。

int Foo()
{
    Bar();
    // aStatement;
    Walk();
    // bStatement;
    Run();
    // cStatement;
    Fly();
    // dStatement;
    return;
}

图2 优点:清洁和日志。 缺点:多次返回。

int Foo() {
    int status;
    status = Bar();
    if (!OK(status)) {
        Log("...");
        return status;
    }
    // aSatement
    status = Walk();
    if (!OK(status)) {
        Log("...");
        return status;
    }
    // bStatement
    status = Run();
    if (!OK(status)) {
        Log("...");
        return status;
    }
    // cStatement
    status = Fly();
    if (!OK(status)) {
        Log("...");
        return status;
    }
    // dSatement
    return status;
}

图3 优点:清洁和日志。 缺点:转到问题。

int Foo() {
    int status;
    status = Bar();
    if (!OK(status)) {
        Log("...");
        goto RETLINE;
    }
    // aSatement
    status = Walk();
    if (!OK(status)) {
        Log("...");
        goto RETLINE;
    }
    // bStatement
    status = Run();
    if (!OK(status)) {
        Log("...");
        goto RETLINE;
    }
    // cStatement
    status = Fly();
    if (!OK(status)) {
        Log("...");
        goto RETLINE;
    }
    // dSatement
RETLINE:
    return status;
}

图4 优点:使用 do while,没有多次返回。 缺点:更多的缩进。

int Foo() {
    int status;

    do {
        status = Bar();
        if (!OK(status)) {
            Log("...");
            break;
        }
        // aStatement
        status = Walk();
        if (!OK(status)) {
            Log("...");
            break;
        }
        status = Run();
        if (!OK(status)) {
            Log("...");
            break;
        }
        // cStatement
        status = Fly();
        if (!OK(status)) {
            Log("...");
            break;
        }
        // dStatement
    } while(false);
    return status;
}

图 5 优点:清洁和一次返回。 缺点:没有日志。

int Foo() {
    int status;
    status = Bar();
    if (Ok(status)) {
        status = Walk();
        // aStatement
    }
    if (OK(status)) {
        // bStatement
        status = Run();
    }
    if (OK(status)) {
        // cStatement
        status = Fly();
    }
    if (Ok(status)) {
        // dStatement
    }
    return status;
}

图6 优点:log & one return。 缺点:缩进更多。

int Foo() {
    int status;

    status = Bar();
    if (!OK(status)) {
        Log("...");
    }
    if (Ok(status)) {
        // aStatement
        status = Walk();
        if (!OK(status)) {
            Log("...");
        }
    }
    if (OK(status)) {
        // bStatement
        status = Run();
        if (!OK(status)) {
            Log("...");
        }
    }
    if (Ok(status)) {
        // cStatement
        status = Fly();
        if (!OK(status)) {
            Log("...");
        }
    }
    if (Ok(status)) {
        // dStatement
    }
    return status;
}

图7 优点:log & one return。 缺点:缩进更多。

int Foo() {
    bool flag = true;
    int status;
    status = Bar();
    if (!OK(status)) {
        Log("...");
        flag = false;
    }
    if (flag) {
        // aStatement
        status = Walk();
        if (!OK(status)) {
            Log("...");
            flag = false;
        }
    }
    if (flag) {
        // bStatement
        status = Run();
        if (!OK(status)) {
            Log("...");
            flag = false;
        }
    }

    if (flag) {
        // cStatement
        status = Fly();
        if (!Ok(status)) {
            Log("...");
            flag = false;
        }
    }
    if (flag) {
        // dStatment
    }
    return status;
}

最佳答案

这是标记为 C++,因此只需使用异常,您就可以编写包含在 try/catch 中的第一个版本。

如果这是第三方库或实际上是 C 代码并且您必须使用返回码,那么我认为选项 2 是合理的。如果多个 return 语句清楚地指示了代码流,那么它们并不是天生的邪恶。

另一种方法是将调用和返回代码检查包装到抛出的模板中:

template <class Callee>
void DoCall(Callee callee)
{
    if(!OK(callee())) throw whatever_exception;
}

关于c++ - 函数怎么写才整齐?考虑日志,一次返回,不再缩进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7905097/

相关文章:

c++ - 来自基类和派生类的多态赋值运算符

c++ - 更快地访问 C++ 数组中的随机元素

c++ - throw 和接住绳子

c++ - 在 C++ OpenCV 中使用相同的变量作为输入和输出是否安全?

java - 为什么 main 不会收到我的返回 int 值 java

ios - 如何以编程方式使用 Swift 获取其他应用程序的崩溃日志

跨集群记录

bash - 如何zgrep没有尾部的gz文件的最后一行

linux fifo,当read peer返回时,write peer也会立即返回?

没有IF返回最大数的算法