James Kuyper said:
Beej Jorgensen wrote: [...]
2. It appears that it's legal to have a function such as int foo(void)
not return a value (as long as it doesn't explicitly "return;"). Is
this the case? I'm having trouble finding the bits of the spec that
describe this situation and what occurs. (gcc will warn with -Wall.)
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."
Notice that the behavior is only undefined if the caller attempts to
use the non-existent return value. Otherwise, it's perfectly
acceptable to reach the } that terminates a function, even if it is
declared as returning a value. I think that writing code which depends
upon this feature is a bad idea, but that's a separate matter.
And I think the reason that rule exists is for compatibility with
pre-ANSI (K&R) C. Prior to the 1989 ANSI standard, there was no
"void", and it wasn't possible to write a function that didn't return
a value. The way to do the equivalent was to depend on the implicit
int rule and neither return a value nor attempt to use the result:
foo() /* implicitly "int foo()" */
{
/* do something */
}
...
foo(); /* ignore non-existent result */
If C89/C90 had made this undefined behavior, it would have broken most
existing C programs. C89 *could* have made the behavior undefined
only if the return type is explicitly declared, but that would have
created a distinction between "foo()" and "int foo()", which are
otherwise identical.
C99 dropped implicit int, and could have dropped this rule, but the
committee chose to lave it in place. For one thing, this means it's
still possible to turn pre-ANSI code into valid C99 code just by
making the implicit int explicit:
int foo()
{
/* do something */
}
...
foo();
Of course the right way to do this is to change it to
"void foo(void)", but there might have been some consideration for
automatic translation of pre-ANSI code.