检查没有return语句的函数的返回值

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

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

5 6 char* handleInput() { 8 fgets(buffer, 1024, stdin); 9 **// return buffer;** <---- COMMENTED RETURN 10 } 11 12 void main() { 14 char* ptr = handleInput(); 15 int flag = atoi(ptr); 16 if (flag < 0) break; 17 printf("You entered: %s\n", ptr); 20 } 

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

C99 6.9.1 / 12“function定义”说:

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

C90 6.6.6.4“ return声明”标准表示具有类似效果的内容:

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

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

我认为这样做的理由是,如果函数没有显式声明(或者如果声明省略了返回类型),则预标准C默认为函数的返回类型int ,并且当C标准化时继续支持。 其中许多function只是为了产生副作用而被调用,并且没有预期或提供的返回值。

几个旁注:

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

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