2011-07-10 150 views
2

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

请帮助我更好地理解这种

 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 } 

回答

10

基本上什么获取返回的好运气。当它返回时你会得到CPU寄存器中的内容。例如,如果返回的值将在AX中,并且char*碰巧在AX中,那么您幸运了。我相信这是一个不确定的行为;即C语言规范不会告诉你应该如何,所以它留给编译器。我很惊讶现代编译器至少不会对你发出警告。

+0

是的。我也期待一个警告。 GCC对此代码很好。没有警告 – JAM

+1

用'gcc -W -Wall -ansi -pedantic'编译,你会看到警告。 –

+1

我敢肯定,警告是存在的。愚蠢的运气很可能是因为fgets实际上返回了缓冲区,这几乎已经在返回寄存器中了,这是Intel盒子上的RAX或EAX(他们在1985年停止使用AX)。因为这是在handleInput中执行的最后一个语句,handleInput返回并返回寄存器中的内容是什么?没错 - 缓冲!您可以查看生成的汇编语言来查看。另外@mac,你编译时是否打开了警告? –

-1

在声明返回值的函数中不使用'return'是不好的做法。大多数编译器应该生成一个警告。

1

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

如果}终止达到的功能,并使用呼叫者的函数调用的值,则行为是不确定的。

C90 6.6.6.4“的return声明”标准说的东西与simialr效果:

如果执行了return声明没有表情,和函数调用的值由主叫,行为是不确定的。达到终止函数的}相当于return没有表达式的语句。

所以从函数返回,而不返回东西从功能上是允许的 - 但函数的调用者不允许使用函数调用的“结果”。这是未定义的行为,与其他答案一样,您可以通过未定义的行为获得“预期”结果,但那只是偶然。

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

一对夫妇旁注:

  • GCC将警告这个如果-Wall选项使用。默认情况下,MSVC会对此进行警告。
  • 由于break不在环路或交换机中,因此您应该收到有关​​行的编译器错误。
  • main()应该返回int而不是void-Wall也会警告这一点)。当然,你也应该明确地返回一些值...