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

问题描述 投票:0回答:1

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

#include <iostream>

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

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

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

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

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

c++ compiler-errors g++
1个回答
2
投票

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

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

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

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

而函数将返回一个未知值

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

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


4
投票

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


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.