That (or something like it) is true for the process as a whole, but not necessarily for main. It's usual to call main from a library-provided function, so it returns just like any other function. This removes the need to special-case main in any way, and provides a space for any system-specific startup and shutdown code.
If you've got VS2012, you can see this code in the file at something like "c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\crt0.c" (it should be easy to find for other versions - it's been in pretty much in that place, with that name, probably with those contents, since VC5 I think).
My post was a bit x86/VC++-specific but the principles have been common to all the C environments I've used. I don't think I've ever used one that by default called your startup function directly, bypassing C runtime initialisation. (Though it's very easy to set this up with Visual Studio.)
If you've got VS2012, you can see this code in the file at something like "c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\crt0.c" (it should be easy to find for other versions - it's been in pretty much in that place, with that name, probably with those contents, since VC5 I think).
For glibc, see http://sourceware.org/git/?p=glibc.git;a=blob;f=csu/libc-sta....
My post was a bit x86/VC++-specific but the principles have been common to all the C environments I've used. I don't think I've ever used one that by default called your startup function directly, bypassing C runtime initialisation. (Though it's very easy to set this up with Visual Studio.)