I am really puzzled that I have to
return from main.
You don't have to. Either main() a any subroutine thereof can enter an
infinitely loop, or call any _Noreturn function, and that would not be
problem (at least, not in itself - if done in the wrong context, it
could cause other problems). The C standard library provides six
_Noreturn functions: longjmp() (which doesn't really count for this
purpose, since it just transfers control to some other part of the
code), abort(), exit(), _Exit(), quick_exit(), and thrd_exit(), and
people are allowed to define similar functions of their own.
main.c:
int main(void)
{
}
The above is not an example of failing to return from main(). There is
an implicit return when execution of a program reaches the end of a
function, which in this case happens immediately at the start of the
program.
bmaxa@maxa:~/examples$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:3:1: warning: control reaches end of non-void function [-Wreturn-type]
}
The problem isn't a failure to return from main; your code does that.
It's failing to provide a return value. main() is declared as returning
an int value, and you've failed to provide one for it to return. Even
that's not necessarily a problem: failing to provide a return value only
has undefined behavior if the calling routine tries to use the return
value that you failed to provide (6.9.1p12). I hope you can understand
why that would be a problem?
There's also a special exemption even from that rule, for main():
reaching the end of main() without returning a value is implicitly
equivalent to "return 0;" (5.1.2.2.3p1).
That's why this is merely a warning, and not an error message. It is a
bad idea to take advantage of the special exemption for main(), and
dangerous to rely upon the exemption for return values that aren't used.
A function that isn't supposed to be returning a value should be
declared void. That return type isn't under your control for main(), so
you should always return some value when exiting main(). However, in
this particular case the behavior is well-defined.
Of three C compilers that I use, only gcc gives warning. What does
it means? Is it something new or was always like that?
The only relevant rule that has changed is the special exemption for
main(), which was added in C99. Before that, failing to return a value
from main() had undefined behavior, because the caller to main() might
(and almost certainly would) try to use the return value you had failed
to provide.