我发现了一个关于我的C++编译器的小怪异。
我有一段不算太复杂的代码需要重构,但是我意外地忘记在某个路径中添加了一个返回语句。我的错。然而这段代码还是编译通过了,当程序执行到那个路径时就会出现segmentation fault错误。
我的问题是:这是编译器的bug吗?还是说C++编译器没有强制要求非void类型的函数必须包含一个return语句?
哦,并且需要明确的是,在这种情况下,它只是一个没有伴随else的无用if语句。没有跳转、退出或者中止的操作。
我发现了一个关于我的C++编译器的小怪异。
我有一段不算太复杂的代码需要重构,但是我意外地忘记在某个路径中添加了一个返回语句。我的错。然而这段代码还是编译通过了,当程序执行到那个路径时就会出现segmentation fault错误。
我的问题是:这是编译器的bug吗?还是说C++编译器没有强制要求非void类型的函数必须包含一个return语句?
哦,并且需要明确的是,在这种情况下,它只是一个没有伴随else的无用if语句。没有跳转、退出或者中止的操作。
个人认为这应该是一个错误:
int f() {
}
int main() {
int n = f();
return 0;
}
但大多数编译器将其视为警告,您甚至可能需要使用编译器开关才能获得该警告。例如,在g ++上,您需要使用-Wall才能获得:
[neilb@GONERIL NeilB]$ g++ -Wall nr.cpp
nr.cpp: In function 'int f()':
nr.cpp:2: warning: no return statement in function returning non-void
当然,使用g++编译时,无论如何都应该至少加上-Wall参数。
不能保证C++编译器会执行此操作。一个C++函数可能通过编译器未知的机制跳出其控制流程。使用 C++ 编写操作系统内核时的上下文切换就是一个例子。由被调用函数抛出但调用者可能无法访问代码的未捕获异常也是其中之一。
有些其他语言,如 Java,在编译时明确强制要求所有路径都返回一个值。在 C++ 中,这并不是真实的情况,就像访问数组越界一样,许多其他情况在语言中也没有得到检查。
enum TriBool { Yes, No, Maybe };
TriBool GetResult(int input) {
if (TestOne(input)) {
return Yes;
} else if (TestTwo(input)) {
return No;
}
}
请记住,C ++并不是为了保护你免受伤害。它是关于让你按照语言的限制做你想做的事情,即使包括自己踩坑。
-Wreturn-type
选项,可能还需要加上-Werror=
。 - Georg Fritzsche