The C standard dictates that code (usually called _start ) create things like stdin, stdout, etc. It has to run BEFORE main() and after main(), since it called main(). In the "after" part _start calls the exit routines you declare in atexit(), for example. Then it executes image rundown code, closing stdin, etc.
You would have to replace _start and _exit and other code in the libc library with your own version. Then link your code against your special version of libc.
is completely compiler dependent. It may well be that a compiler supports this feature.
The reason main() is a function is because it's called by something. That something has to run before main() can come into play.