Thank you for clarification of the question on my request.
Yes, if you try to create more then one, the development environment should give you an error like "overloading of main is not allowed" or something.
So, how the run-time system knows what signature to use while calling the method? In general case, no reflection is possible (like in .NET), so how to determine what parameters to pass?
Short answer is: it is possible due to
__cdecl
,
by passing maximum number of parameters in all cases and always using return value.
First, pay attention that all signatures are compatible: more "advanced" signature only adds additional parameters:
int main(void)
int main(int argc, char **argv)
int main(int argc, char *argv[]) int main(int argc, char **argv, char **envp)
(
http://en.wikipedia.org/wiki/Main_function#C_and_C.2B.2B[
^])
The trick is here: the argument passing conventions. It is always
__cdecl
. This is the only convention when the stack cleanup is done by the caller, not the callee:
http://msdn.microsoft.com/en-us/library/984x0h58%28v=vs.71%29.aspx[
^].
In this case, the caller can pass all the parameters as in the case of the longest signature and always returns
int
value. As the return value is returned in the CPU register, it does not disrupt the operation on the called function does not use it: it is simply ignored. All the parameters are available on the stack, so the called function only uses as many as its signature allows; all other are just ignored. As the stack is cleaned up by the caller (run-time system),
it does not need to know what was the actual signature of the callee — all parameters are passed, and, respectively, all are removed by the caller.
Try to specify the calling conventions explicitly:
int __cdecl main(int argc, char **argv)
It will compile and link. Try to use
__stdcall
or any other — the linker will fail. You can only use
__cdecl
. This is designed so by the reasons I explained above.
—SA