问题
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 throw an error?
For example,
int func1() {
return; // error
}
int func2() {
// does not return anything
}
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.
回答1:
In C++, such code has undefined behaviour:
[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.
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).
Consider
int func3() {
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.
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.
回答2:
In C, quoting N1256 6.9.1p12:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
So it's legal (but a bad idea) for a non-void function to fail to return a value, but if it does so and the caller attempts to use the result, the behavior is undefined. Note that it doesn't necessarily just return some arbitrary value; as far as the standard is concerned, anything is possible.
Pre-ANSI C didn't have the void
keyword, so the way to write a function that didn't return a value was to leave out the return type, making it implicitly return int
. Requiring a return
statement in a value-returning function would have broken old code. It would also have required extra analysis by the compiler to determine that all code paths hit a return
statement; such analysis is reasonable for modern compilers, but might have been an excessive burden when C was first standardized.
C++ is slightly more strict. In C++:
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.
so the behavior is undefined whether the caller attempts to use the (nonexistent) result or not.
C and C++ compilers certainly can warn about missing return
statements, or about control paths that fall off the end of a function without executing a return
statement, but the respective standards do not require them to do so.
回答3:
In C, it is actually legal for a non-void function to finish without returning a value, as long as the calling code doesn't try to use the return value.
On the other hand a return
statement without an expression is not allowed to appear in a non-void function.
The relevant parts of the C99 standard are §6.9.1 for the first case:
If the
}
that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
and §6.8.6.4 for the second case:
A
return
statement without an expression shall only appear in a function whose return type isvoid
.
回答4:
Both of your functions are ill formed. The difference between them is that your func1
violates the rules about how the return
statement can be used while your func2
is undefined behavior. The return
statement in your func1
is illegal and an implementation must diagnose this. The lack of a return statement in your func2
is undefined behavior. Most compilers will diagnose this, but none have to.
来源:https://stackoverflow.com/questions/9936011/if-a-function-returns-no-value-with-a-valid-return-type-is-it-okay-to-for-the