R. Clayton (rclayton@monmouth.edu)
(no date)
I have a recursive function that returns an int. In one of the branches I
forgot to return a value, but my program compiled and worked correctly. Why is
that?
This is an unhappy legacy from C. C did not require that functions explicitly
return a value.
$ cat t.c
#include <stdio.h>
int f() { }
int main() { printf("%d\n", f()); }
$ gcc t.c
$ ./a.out
133388
$ cc t.c
$ ./a.out
133640
$
If a function doesn't have an explicit return value, then the value that
happens to be in the return register is the function's return value.
C++, being a descendant of C, keep that disreputable feature.
$ cat t.cc
#include <iostream>
int f() { }
int main() { std::cout << f() << "\n"; }
$ g++ t.cc
$ ./a.out
134920
$
However, some C++ compilers are more strict than others.
$ CC t.cc
"t.cc", line 2: Error: "f()" is expected to return a value.
1 Error(s) detected.
$
And almost all compilers have options that will warn you of functions without
explicit returns.
$ cc -v t.c
"t.c", line 2: warning: Function has no return statement : f
"t.c", line 3: warning: Function has no return statement : main
$ gcc -Wall t.c
t.c: In function `f':
t.c:2: warning: control reaches end of non-void function
t.c: In function `main':
t.c:3: warning: control reaches end of non-void function
$ g++ -Wall t.cc
t.cc: In function `int f()':
t.cc:2: warning: control reaches end of non-void function
$
There is no warning about main() in the last example because standard C++
requires that main() with no explicit return statment always returns a 0.
In your case, you lucked out. Becuase your function is making recursive
calls, the return value from the previous call is still in the return
register, and that value served as the return value for the calls that didn't
explicitly return a value.
int f(int n)
if n < 0
return 0
else
f(n - 1)
Unfortunately, you can't depend on that behavior; the compiler is allowed to
make any changes it wants to registers between calls, including changing the
contents of the return register. This code also depends on the fact that the
return value didn't change between calls (it's always 0). If this code had
to change the return value, then your program wouldn't have worked.
This archive was generated by hypermail 2.0b3 on Thu Dec 18 2003 - 16:15:05 EST