La maggior parte delle volte non è necessario preoccuparsi. Solitamente userete __cdecl
, ma solo perché è l'impostazione predefinita in Visual C++. Le funzioni membro C++, tuttavia, utilizzano la convenzione __thiscall
per impostazione predefinita in Visual C++
Una situazione (piuttosto comune) in cui si deve davvero preoccuparsi di chiamare le convenzioni quando si passano i callback alle funzioni API, come quelle dell'API di Windows:
// CALLBACK is #define'd as __stdcall
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg
WPARAM wParam, LPARAM lParam);
// ...
windowClass.lpfnWndProc = &MyWndProc;
::RegisterClass(&windowClass);
Qui, dichiariamo MyWndProc()
ad avere la __stdcall
convenzione (CALLBACK
è #define
'd come __stdcall
). Questo è necessario perché il sistema operativo si aspetta che lpfnWndProc
punti a WNDPROC
, which uses the CALLBACK
convention.
Quasi ogni funzione API di Windows che accetta un callback richiede le funzioni di callback per utilizzare la convenzione __stdcall
, e dal momento che è di solito __cdecl
il default, è necessario rendere questo esplicito (si usa CALLBACK
per le procedure di finestra).
Questo è estremamente importante perché il danneggiamento dello stack può verificarsi se il sistema operativo tenta di chiamare una funzione non __stdcall
. Sfortunatamente la gente ha sbagliato questo Windows will actually check for calling convention mismatch specifically for window procedures.
Mentre è necessario il __stdcall
per le funzioni di callback passate alle funzioni WinAPI, le funzioni che accettano un numero variabile di argomenti devono utilizzare la convenzione di chiamata __cdecl
, poiché solo il chiamante saprà come estrarre correttamente il numero variabile di argomenti dallo stack. Dal momento che l'impostazione predefinita è __cdecl
, non è necessario specificare esplicitamente __cdecl
per le funzioni che accettano un numero variabile di argomenti.
Personalmente non ho trovato un utilizzo per __fastcall
, anche se sono sicuro che qualcuno lo ha.
__clrcall
è rilevante solo se si interagisce con il codice gestito.