且构网

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

为什么在不返回值的情况下从非 void 函数的末尾流出不会产生编译器错误?

更新时间:2022-11-11 12:43:48

C99 和 C++ 标准不要求函数返回值.值返回函数中缺少的 return 语句将仅在 main 函数中定义(返回 0).

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.

来自 C++11 草稿:

§ 6.6.3/2

从函数末尾流出 [...] 会导致返回值的函数出现未定义的行为.

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

§ 3.6.1/5

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

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

return 0;

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

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

如果你用 -Wreturn-type 选项调用它,gcc 会给你一个警告.

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

-Wreturn-type 每当函数定义的返回类型为默认为 int.也警告任何没有返回值的 return 语句在返回类型不是的函数中无效(从末端掉落函数体被认为是返回没有价值),以及关于回报在 a 中带有表达式的语句返回类型为 void 的函数.

-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.

此警告由 -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

此代码具有正式未定义的行为,实际上它是 调用约定架构 依赖.在一个特定的系统上,使用一个特定的编译器,返回值是最后一个表达式求值的结果,存储在该系统处理器的 eax 寄存器中.

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.