【问题标题】:Checking return value of a function without return statement检查没有返回语句的函数的返回值
【发布时间】:2011-10-02 02:38:39
【问题描述】:

请解释为什么有时不需要返回语句?

函数有返回类型,但缺少返回语句。同时,程序编译并运行良好。

请帮助我更好地理解这一点

char* handleInput() {
    fgets(buffer, 1024, stdin);
//    return buffer;       <---- COMMENTED RETURN
}

void main() {
        char* ptr = handleInput();
        int flag = atoi(ptr);    
        if (flag < 0) break;    
        printf("You entered: %s\n", ptr);
}

【问题讨论】:

    标签: c return-value


    【解决方案1】:

    基本上得到的回报是愚蠢的运气。当它返回时,您会得到 CPU 寄存器中发生的情况。例如,如果返回值在 AX 中,而 char* 恰好在 AX 中,那么您很幸运。我相信这是一种未定义的行为;即 C 语言规范并没有告诉您应该做什么,所以它留给了编译器。我很惊讶现代编译器至少不会向您发出警告。

    【讨论】:

    • 是的。我也期待一个警告。 GCC 对这段代码很好。没有警告
    • gcc -W -Wall -ansi -pedantic编译你会看到警告。
    • 我确定警告存在。运气不好很可能是因为 fgets 实际上返回了缓冲区,几乎可以肯定,它已经在返回寄存器中,即英特尔机器上的 RAX 或 EAX(他们在 1985 年停止使用 AX :))。因为它是在handleInput 中执行的最后一条语句,所以handleInput 返回,返回寄存器中的内容是什么?没错——缓冲!您可以查看生成的汇编语言来了解这一点。还有@mac,你编译时打开警告了吗?
    • @Ray Toal - 感谢您的更新,我不是装配工 ;)
    【解决方案2】:

    C99 6.9.1/12“函数定义”说:

    如果到达终止函数的 },并且调用者使用了函数调用的值,则行为未定义。

    C90 6.6.6.4“return 声明”标准说了一些类似的东西:

    如果执行了不带表达式的return 语句,并且调用者使用了函数调用的值,则行为未定义。到达终止函数的} 等效于没有表达式的return 语句。

    因此,允许从函数返回而不从函数返回 something - 但不允许函数的调用者使用函数调用的“结果”。这是未定义的行为,就像其他答案提到的那样,您可以获得未定义行为的“预期”结果,但这只是偶然。

    我相信这样做的理由是,如果未显式声明函数(或者如果声明省略了返回类型),则预标准 C 默认为函数的返回类型 int,并且这种情况继续存在当 C 标准化时支持。其中许多函数被设计为仅针对它们产生的副作用调用,并且没有预期或提供返回值。

    一些旁注:

    • 如果使用-Wall 选项,gcc 将对此发出警告。默认情况下,MSVC 会发出警告。
    • 您应该收到关于 if (flag &lt; 0) break; 行的编译器错误,因为 break 不在循环或开关中。
    • main() 应该返回 int 而不是 void-Wall 也会对此发出警告)。当然,您还应该明确返回一些值...

    【讨论】:

      【解决方案3】:

      在声明为返回值的函数中不使用“return”至少可以说是不好的做法。大多数编译器都会生成警告。

      【讨论】:

        猜你喜欢
        • 2011-06-06
        • 2011-10-26
        • 1970-01-01
        • 1970-01-01
        • 2016-08-27
        • 2018-06-22
        相关资源
        最近更新 更多