There is no special treatment of main in the major C compilers, the only "magic" thing the compiler does is including the CRT startup object file in the link, which defines _start as a function ultimately calling main, and having the default linker script set the address of "_start" as the executable entry point.
You can pass -nostdlib to gcc to disable linking the CRT startup object (or use ld directly) and you can pass --default-script /dev/null to ld to disable the linker script.
There is no need to declare main or check arguments or return types since in C arguments are both pushed and popped by the caller and the language provides no typing guarantees and thus there is no problem in calling functions with mismatched argument or return type declarations.
Yes there is. I've demonstrated this in a sibling (or rather, cousin) comment, but in short, you can happily not return a value in main even if its type is "int main(void)". Try that with another function, and the compiler should at least warn. This might not be a special case of code generation, but it is a special case of error handling at least.
It doesn’t do that if you set the historical stack alignment, though (-mpreferred-stack-boundary=2), or if you name the function anything else but main (it even does a tail call). Presumably it’s trying to (somewhat) recover from the time when the GCC authors accidentally the SysV i386 ABI[1,2].
You can pass -nostdlib to gcc to disable linking the CRT startup object (or use ld directly) and you can pass --default-script /dev/null to ld to disable the linker script.
There is no need to declare main or check arguments or return types since in C arguments are both pushed and popped by the caller and the language provides no typing guarantees and thus there is no problem in calling functions with mismatched argument or return type declarations.