为什么一个有返回类型但不返回任何东西的函数不会编译失败?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么一个有返回类型但不返回任何东西的函数不会编译失败?相关的知识,希望对你有一定的参考价值。

考虑下面的例子,用g++ 5.4编译(仅)。

#include <iostream>

int foo()
{
    std::cout << "foo" << std::endl;
}

int main()
{
    std::cout << foo();
    return 0;
}

foo() 没有任何 return 语句,代码编译后,函数会返回一个未知值,当返回类型是指针时,也会发生同样的情况--这可能会导致一个分段故障。

为什么编译这样的函数时没有错误警告?

是C++标准的问题还是实现的问题?

答案

为什么在编译这样的函数时,没有出现错误...?

因为程序的格式很好。编译器需要成功编译所有格式良好的程序。

为什么编译这样的函数时没有...警告?

标准不要求有警告。旧版本的GCC只有在你要求编译器这样做的情况下才会对这样的错误进行警告。GCC 8默认启用了这个特殊的警告。

而函数将返回一个未知值

不尽然。如果执行到非void函数的末端而没有返回,程序的行为是未定义的,所以这种情况可能发生,也可能不发生。

请注意,在流插入操作符发生抛出或终止程序的情况下,该函数实际上会有很好的行为定义。我们知道,流插入并不能保证抛出也不能保证终止程序,这其实会让人很惊讶。但是编译器不能做这样的概括。

另一答案

语言定义中说,这会产生未定义的行为。那是因为有时无法诊断它。警告你这种事情的编译器偶尔会出错。我曾为了让一个编译器闭嘴而添加了一个不需要的返回语句,结果另一个编译器抱怨这个返回语句是 "不可到达的代码"

另一答案

我使用的是g++ 9.3.0,所以对g++ 5.4不能说太多。

在旧版本中,如果你的C++程序缺少了一个本应返回值的函数的返回语句,g++会很高兴地编译它,不会出现任何错误(甚至警告,除非使用-Wreturn-type或-Wall或-Werror=return-type)。试图使用函数的返回值,很可能会引起一个分段故障。

如果你想要这种行为,请使用-Werror=return-type

以上是关于为什么一个有返回类型但不返回任何东西的函数不会编译失败?的主要内容,如果未能解决你的问题,请参考以下文章

Java中,构造函数没有返回值。请问没有返回值和返回值类型为void,有啥区别?

构造函数

php函数 返回值

构造函数主要特点

Angular 2 Firebase Observable 承诺不会返回任何东西

为啥调用存储过程不返回任何东西?