且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么流下非空函数的结尾而不返回无法产生一个编译错误的值?

更新时间:2023-11-12 23:53:22

C99和C ++标准不要求函数返回一个值。在一个返回值的函数缺少return语句将被定义(返回 0 )仅在功能。

的理由包括检查是否每code路径返回的值是相当困难的,和一个返回值可以与嵌入式汇编或其他棘手的方法进行设置。

C ++ 11 草案:

第6.6.3 / 2


  

流下一个函数的结尾[...]结果不确定的行为在一个返回值的功能。


块引用>

第3.6.1 / 5


  

如果控制达到没有遇到一个收益语句,其效果是在执行的结束p>

 返回0;


块引用>

请注意,该行为描述的C ++ 6.6.3 / 2是不是在C.同一


GCC会给你一个警告,如果你-Wreturn与类型选项调用它。


  

-Wreturn型警告每当函数具有返回类型定义
  默认为int。还警告任何
  没有返回值return语句
  在一个函数的返回类型是不
  无效(脱落的结束
  函数体被认为回归
  没有值),和大约一回
  用在一个前pression声明
  函数,它的返回类型为void。


  
  

被启用此警告的 -Wall


块引用>

就像一个好奇,看看这是什么code的作用:

 的#include<&iostream的GT;INT富(){
   INT 1 = 5;
   INT B = A + 1;
}INT的main(){性病::法院LT&;<富()<<的std :: ENDL; } //可以打印6

这code已正式未定义的行为,并在实践中的调用约定并的架构依赖。在一个特定的系统中,有一个特殊的编译器,返回值是最后前pression评估的结果,存储在该系统的处理器的 EAX 寄存器。

Ever since I realized many years ago, that this doesn't produce an error by default, (in gcc at least) I've always wondered why?

I understand that you can issue compiler flags to produce a warning, but shouldn't it always be an error? Why does it make sense for a non-void function not returning value to be valid?

An example as requested in the comments:

#include <stdio.h>
int stringSize()
{
}

int main()
{
    char cstring[5];
    printf( "the last char is: %c\n", cstring[stringSize()-1] ); 
    return 0;
}

...compiles.

C99 and C++ standards don't require functions to return a value. The missing return statement in a value-returning function will be defined (to return 0) only in the main function.

The rationale includes that checking if every code path returns a value is quite difficult, and a return value could be set with embedded assembler or other tricky methods.

From C++11 draft:

§ 6.6.3/2

Flowing off the end of a function [...] results in undefined behavior in a value-returning function.

§ 3.6.1/5

If control reaches the end of main without encountering a return statement, the effect is that of executing

return 0;

Note that the behaviour described in C++ 6.6.3/2 is not the same in C.


gcc will give you a warning if you call it with -Wreturn-type option.

-Wreturn-type Warn whenever a function is defined with a return-type that defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void (falling off the end of the function body is considered returning without a value), and about a return statement with an expression in a function whose return-type is void.

This warning is enabled by -Wall.


Just as a curiosity, look what this code does:

#include <iostream>

int foo() {
   int a = 5;
   int b = a + 1;
}

int main() { std::cout << foo() << std::endl; } // may print 6

This code has formally undefined behaviour, and in practice it's calling convention and architecture dependent. On one particular system, with one particular compiler, the return value is the result of last expression evaluation, stored in the eax register of that system's processor.