views:

42

answers:

1

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.

+7  A: 

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:

// CALLBACK is #define'd as __stdcall 
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg 
    WPARAM wParam, LPARAM lParam); 
// ... 
windowClass.lpfnWndProc = &MyWndProc; 
::RegisterClass(&windowClass);

Here, we declare MyWndProc() as having the __stdcall convention (CALLBACK is #define'd as __stdcall). This is needed because the operating system expects that lpfnWndProc points to a WNDPROC, which uses the CALLBACK 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 use CALLBACK 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.

In silico