为什么流出一个非void函数的结尾而不返回一个值不会产生编译器错误? [英] Why does flowing off the end of a non-void function without returning a value not produce a compiler error?

查看:201
本文介绍了为什么流出一个非void函数的结尾而不返回一个值不会产生编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我意识到很多年前,这不会产生一个错误默认情况下(至少在gcc)我一直想知道为什么?



我理解你可以发出编译器标志来产生警告,但不应该总是一个错误?为什么非空函数不返回值有效是有意义的?



注释中请求的示例:

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

int main()
{
char cstring [5]
printf(最后一个字符是%c \\\
,cstring [stringSize() - 1]);
return 0;
}

...编译。

解决方案

C99和C ++标准不需要返回值的函数。仅在 main 函数中定义一个值返回函数中缺少的返回语句(仅返回 0 )。



基本原理包括检查每个代码路径是否返回值非常困难,并且可以使用嵌入式汇编器或其他棘手方法设置返回值。



C ++ 11 草稿:



§6.6.3 / 2


流程结束函数[...]价值回报函数中的行为。


§3.6.1 / 5



< blockquote>

如果控制到达 main 的结尾而没有遇到 return 语句,是执行

  return 0; 


请注意,C ++ 6.6.3 / 2中描述的行为在C中不一样。






如果您使用-Wreturn类型选项调用gcc,将会向您发出警告。 / p>

-Wreturn-type 当函数定义为返回类型时,警告
默认为int。同时在返回类型不是
的函数中警告任何
返回语句没有返回值
void(掉落
函数体的结尾被认为是返回
没有值),以及返回
语句,其中的
函数的表达式的返回类型为void。



此警告是由 -Wall 启用。


正如好奇心,看看这段代码的作用:

  include< iostream> 

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

int main(){std :: cout<< foo()<< std :: endl; } //可以打印6

此代码具有正式未定义的行为,在实践中调用约定 architecture dependent。在一个特定的系统上,使用一个特定的编译器,返回值是最后表达式计算的结果,存储在系统处理器的 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.

这篇关于为什么流出一个非void函数的结尾而不返回一个值不会产生编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆