如何使我的功能 "return a value in all control paths"?

How do I make my function "return a value in all control paths"?

我是编程新手,我正在尝试组合一个函数:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

string name;

bool check(string word)
{
    for(int i = 0; i >= 9; i++)
    {
        if (strcmp(name, word) == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

int main(void)
{
    
}

但是当我尝试编译时,收到错误消息 error: non-void function does not return a value in all control paths [-Werror,-Wreturn-type]。这是什么意思,我该如何解决?

要修复警告,请在 check:

末尾添加一个 return
bool
check(string word)
{
    for (int i = 0; i >= 9; i++) {
        if (strcmp(name, word) == 0) {
            return true;
        }
        else {
            return false;
        }
    }

// NOTE/FIX: fixes the warning
    return false;
}

但是,check 函数中的 for 循环不执行任何操作(它在每次迭代时执行 相同的 操作),因此您不需要需要循环。

此外,请注意,您 从未 name 初始化为任何内容,因此它会出现段错误,因为 string 实际上是 char *。您需要将其设置为有效的指针值。

这是一个带有诊断测试的重构版本:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

string name = "hello";

bool
check(string word)
{
    bool match;

    match = (strcmp(name,word) == 0) ? true : false;

    return match;
}

string testlist[] = {
    "hello", "world", NULL
};

int
main(void)
{

    for (string *cur = testlist;  *cur != NULL;  ++cur) {
        bool ok = check(*cur);
        printf("%s: %s\n",*cur,ok ? "match" : "fail");
    }

    return 0;
}

程序输出如下:

hello: match
world: fail

Can you help me with the code in your first paragraph- it looks like it will simply return false at the end?

当然可以。你是对的。它只是在末尾添加了一个return语句[with一个值]。

糟糕。我刚刚注意到你的 for 循环将 永远不会 被执行,甚至 一次 。那是因为 i 被初始化为 0。但是,循环条件是 i >= 9,在第一次迭代时将是 false

事实上,编译器的优化器会检测到这一点并完全消除循环。

如果你想[出于某种原因]循环10次,正确的for循环应该是:

for (int i = 0; i <= 9; i++)

使用这个更正的循环,添加的return永远不会实际执行。这是因为循环现在 保证 至少执行 一次

它将尝试循环 10 次。但是,if 要么为真,要么为假,并且在 任一 情况下,它从 执行 return循环,所以事情就此停止。

执行 final/added return.

永远不会“脱离”循环

但是,编译器无法“知道”这一点。

或者,更重要的是,它仍然应该在底部标记缺少 return,即使它确实意识到它在实践中不会被执行。

它看到的是for循环执行完后,到了函数的底部,对于一个returns的函数值,并且该代码路径有 no return 语句 [with value]。

你的循环从不执行任何迭代。在for(int i = 0; i >= 9; i++)中,i被初始化为0,然后循环只在i >= 9时执行。那不是真的(零不大于或等于九),所以循环不执行。程序控制继续到循环之后,您没有更多的代码,只是函数的结尾。所以函数在没有使用 return 语句的情况下退出,所以没有返回值。因此编译器会警告你。

如果将循环更改为for(int i = 0; i <= 9; i++),则循环将执行,并且根据循环内的代码,肯定会执行return 语句。但是,Clang 和 GCC 编译器仍然会发出警告。据推测,他们这样做是因为存在一个假设的代码路径,其中循环结束并且函数如上所述退出。这不可能发生,但两个编译器都无法推断出它,我觉得这有点令人惊讶。由于他们无法识别没有 return 的路径无法执行,因此他们发出警告。

避免警告的一种方法是在函数末尾放置一个 return 语句。