That calling convention on x86 specifies that the return value is red from the EAX register. So, when your main() function exits, the return value is red from EAX, it's that simple.
The compilers may add boilerplate code around the main, in fact main() is rarely the real main() function, but that doesn't change the spec.
And as I've just tested, gcc doesn't return zero termination status if you reach the } at the end of main.
The main() is called like a regular function, by the system thing that executes programs.
Depending on the compiler and the flags, the main() is not the real entry point of the program. It can add another entry point to do some magic, like setting the return code.
int main()
{
int a = 12;
}
$ gcc maintest.c
$ ./a.out
$ echo $?
148 $ cat test.c
int main(void) {int a = 12;}
$ gcc-6 test.c -o test --std=c89; ./test; echo $?
162
$ gcc-6 test.c -o test --std=c99; ./test; echo $?
0
Must be a C99 thing. int main(void)
{
__asm {
mov eax, 123
}
}
// visual studio command line
// cl testc.c
// cl testcpp.cpp
// testc.exe
// echo C %errorlevel%
// testcpp.exe
// echo CPP %errorlevel%
Indeed. It's a C99 thing.For those not familiar with MSVC. The C compiler is not C99 compliant and the C++ compiler is.
Often this is as easy as coding to an older standard, like C89 with a few selected features from later standards, and adding some compatibility features / problem detection in the build system.
And don't rely on features that are difficult to explain and/or add only questionable value. Just return 0 from main, it's the obvious simple thing to do.