I found this:
Because the stack is cleaned by the called function, the __stdcall calling convention creates smaller executables than __cdecl, in which the code for stack cleanup must be generated for each function call.
Suppose I got 2 functions:
void __cdecl func1(int x)
{
//do some stuff using x
}
void __stdcall func2(int x, int y)
{
//do some stuff using x, y
}
and here in the main()
:
int main()
{
func1(5);
func2(5, 6);
}
IMO, it is main()
's responsibility to clean up the stack of the call to func1(5)
, and func2
will clean up the stack of the call to func2(5,6)
, right?
Four questions:
1.For the call to func1
in main()
, it's main
's responsibility to clean up the stack, so will compiler insert some code (code to clean up the stack) before and after the call to func
? Like this:
int main()
{
before_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call
func1(5);
after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of cdecl-func-call
func2(5, 6);
}
2.For the call to func2
in main()
, it's func2
's own job to clean up the stack, so I presume, no code will be inserted in main()
before or after the call to func2
, right?
3.Because func2
is __stdcall
, so I presume, compiler will automatically insert code (to clean up the stack) like this:
void __stdcall func1(int x, int y)
{
before_call_to_stdcall_func(); //compiler generated code for stack-clean-up of stdcall-func-call
//do some stuff using x, y
after_call_to_cdecl_func(); //compiler generated code for stack-clean-up of stdcall-func-call
}
I presume right?
4.Finally, back to the quoted words, why __stdcall
results in smaller executable than __cdecl
? And there is no such a thing as __stdcall
in linux, right? Does it means linux elf will be always larger than exe in win?
__stdcall
generates no cleanup code at the call site, however, it should be noted that compilers can accrue stack cleanup from multiple __cdecl
calls into one cleanup, or it can delay the cleanup to prevent pipeline stalls.__cdecl
function, setting up of function arguments is something different (different compilers generate/prefer different methods).__stdcall
was more a windows thing, see this. the size of the binary depends on the number of calls to the __cdecl
funcs, more calls means more clean up code, where as __stdcall
has only 1 singular instance of cleanup code. however, you shouldn't see that much size increase, as at most you have a few bytes per call.*Its important to distinguish between cleanup and setting up call parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With