What are the key factors on using different calling conventions? When does someone know to use specific calling conventions such as __cdecl
or __stdcall
or __fastcall
in different occasions.
Examples would be really apprciated.
What are the key factors on using different calling conventions? When does someone know to use specific calling conventions such as __cdecl
or __stdcall
or __fastcall
in different occasions.
Examples would be really apprciated.
Most of the time you don't need to worry about it. Usually you'll use
__cdecl
, but only because that's the default in Visual C++. C++ member functions, however, use the__thiscall
convention by default in Visual C++A (rather common) situation where you really have to worry about calling conventions is when you pass callbacks to API functions, like those in the Windows API:
Here, we declare
MyWndProc()
as having the__stdcall
convention (CALLBACK
is#define
'd as__stdcall
). This is needed because the operating system expects thatlpfnWndProc
points to aWNDPROC
, which uses theCALLBACK
convention.Just about every Windows API function that accepts a callback requires the callback functions to use the
__stdcall
convention, and since__cdecl
is usually the default, you must make this explicit (you would useCALLBACK
for window procedures).This is extremely important because stack corruption can occur if the operating system attempts to call a non-
__stdcall
function. Unfortunately enough people get this wrong that Windows will actually check for calling convention mismatch specifically for window procedures.While
__stdcall
is required for callback functions passed to WinAPI functions, functions that accept a variable number of arguments must use the__cdecl
calling convention, because only the caller will know how to properly pop the variable number of arguments off the stack. Since__cdecl
is usually the default, you don't need to explicitly specify__cdecl
for functions that accept a variable number of arguments.I personally haven't found a use for
__fastcall
, although I'm sure someone has.__clrcall
is relevant only if you're interacting with managed code.