如果一个函数没有返回值,但返回类型有效,编译器是否可以返回垃圾?
如果一个函数的返回类型不是void
,并且该函数没有返回任何东西,那么我猜编译器会返回一个垃圾值(可能被视为一个未初始化的值).它发生在编译时,为什么不应该显示错误?
If a function has a return type other than void
, and the function does not return anything, then I guess the compiler returns a garbage value (possibly seen as an uninitialized value). It happens at compile time, so why shouldn't it show an error?
例如,
int func1() {
return; // error
}
int func2() {
// does not return anything
}
第二个 func2
应该抛出一个错误,但它不会.有什么原因吗?我的想法是,它可以看作是一个未初始化的值,所以如果我们需要在第二种情况下抛出错误,那么我们需要抛出错误,如果一个值未初始化,比如说
The second func2
should throw an error, but it does not. Is there a reason for it? My thinking was such that, it can be seen as an uninitialized value, so if we need to throw an error in the second case, then we need to throw error, if an value is uninitialized, say
int i; // error
int i = 6; // okay
有什么想法,或者这是一个重复的问题?感谢您的帮助.
Any thoughts, or is this a duplicate question? I appreciate your help.
推荐答案
在 C++ 中,这样的代码有未定义的行为:
In C++, such code has undefined behaviour:
[stmt.return]/2 ... 从函数末尾流出相当于没有值的返回;这会导致值返回函数中的未定义行为....
[stmt.return]/2 ... Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function. ...
大多数编译器都会对与问题中的代码类似的代码产生警告.
Most compilers will produce a warning for code similar to that in the question.
C++ 标准不要求这是编译时错误,因为在一般情况下,很难正确确定代码是否真的在函数末尾运行,或者函数是否通过异常退出 (或 longjmp 或类似机制).
The C++ standard does not require this to be a compile time error because in the general case it would be very difficult to correctly determine whether the code actually runs off the end of the function, or if the function exits through an exception (or a longjmp or similar mechanism).
考虑
int func3() {
func4();
}
如果 func4()
抛出,那么这段代码完全没问题.编译器可能看不到func4()
的定义(因为单独编译),所以不知道会不会抛出.
If func4()
throws, then this code is totally fine. The compiler might not be able to see the definition of func4()
(because of separate compilation), and so cannot know whether it will throw or not.
此外,即使编译器可以证明 func4()
没有抛出异常,它仍然必须证明 func3()
确实被调用才能合法地调用拒绝程序.这种分析需要对整个程序进行检查,这与单独编译是不兼容的,在一般情况下甚至是不可能的.
Furthermore, even if the compiler can prove that func4()
does not throw, it would still have to prove that func3()
actually gets called before it could legitimately reject the program. Such analysis requires inspection of the entire program, which is incompatible with separate compilation, and which is not even possible in the general case.
相关文章