假设我有以下功能:

// Precondition:  foo is '0' or 'MAGIC_NUMBER_4711'
// Returns:       -1 if foo is '0'
//                 1 if foo is 'MAGIC_NUMBER_4711'
int transmogrify(int foo) {
    if (foo == 0) {
        return -1;
    } else if (foo == MAGIC_NUMBER_4711) {
        return 1;
    }
}

编译器提示“缺少 return 语句”,但我知道 foo 永远不会有与 0MAGIC_NUMBER_4711 不同的值,否则我的函数将没有定义的语义。

对此有哪些更好的解决方案?
这真的是一个问题,即标准怎么说?

最佳答案

有时,您的编译器无法推断您的函数实际上没有丢失的返回值。在这种情况下,有几种解决方案:

假设以下简化代码(尽管现代编译器会看到没有路径泄漏,只是示例性的):

if (foo == 0) {
    return bar;
} else {
    return frob;
}

重构你的代码
if (foo == 0) {
    return bar;
}
return frob;

如果您可以将 if 语句解释为一种防火墙或先决条件,那么这很有效。

中止()
if (foo == 0) {
    return bar;
} else {
    return frob;
}
abort(); return -1; // unreachable

相应地返回其他东西。该评论告诉其他程序员和您自己为什么会出现这种情况。


#include <stdexcept>

if (foo == 0) {
    return bar;
} else {
    return frob;
}

throw std::runtime_error ("impossible");

单功能导出点的缺点

控制流

有些人退回到 one-return-per-function a.k.a. single-function-exit-point 作为解决方法。这在 C++ 中可能被视为过时,因为您几乎永远不知道该函数将在哪里真正退出:
void foo(int&);

int bar () {
    int ret = -1;
    foo (ret);
    return ret;
}

看起来不错,看起来像 SFEP,但逆向工程第 3 方专有 libfoo 显示:
void foo (int &) {
    if (rand()%2) throw ":P";
}

如果 bar()nothrow,则此参数不成立,因此只能调用 nothrow 函数。

复杂

每个可变变量都会增加代码的复杂性,并给代码维护者的大脑能力带来更大的负担。这意味着更多的代码和更多的状态需要测试和验证,反过来意味着你从维护者的大脑中吸取了更多的状态,反过来意味着更少的维护者的大脑容量留给重要的东西。

缺少默认构造函数

有些类没有默认构造,如果可能的话,您将不得不编写真正的伪造代码:
File mogrify() {
    File f ("/dev/random"); // need bogus init because it requires readable stream
    ...
}

只是为了宣布它,这真是一个黑客。

关于c++ - "missing return statement",但我知道它在那里,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9570823/

10-16 06:59