检查函数的返回值而不返回return语句

Jam*_*sev 2 c return-value

使用下面的例子,请解释为什么有时候不需要return语句?函数具有返回类型,但缺少return语句.同时,程序编译和工作正常.

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

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);
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*sco 11

基本上返回的是愚蠢的运气.当它返回时,你会得到CPU寄存器中发生的事情.例如,如果返回的值在AX中,并且char*碰巧在AX中,那么你很幸运.我相信这是一种不确定的行为; 即C语言规范没有说明你应该这样做,所以留给编译器.我很惊讶现代编译器至少不会向你发出警告.


Mic*_*urr 5

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

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

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

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

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

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

几个边注:

  • 如果使用该-Wall选项,gcc 将对此发出警告。默认情况下,MSVC 会对此发出警告。
  • 您应该收到有关该if (flag < 0) break;行的编译器错误,因为该行break不在循环或切换中。
  • main()应该返回int不能void-Wall将警告有关为好)。当然,你也应该显式地返回一些值......