La plupart du temps, vous n'avez pas besoin de vous en préoccuper. Habituellement, vous utiliserez __cdecl
, mais seulement parce que c'est la valeur par défaut dans Visual C++. Les fonctions membres C++, cependant, utilisent la convention __thiscall
par défaut dans Visual C++
Une situation (plutôt commune) où vous devez vraiment vous préoccuper des conventions d'appel est lorsque vous passez des rappels aux fonctions de l'API, comme celles de l'API Windows:
// CALLBACK is #define'd as __stdcall
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg
WPARAM wParam, LPARAM lParam);
// ...
windowClass.lpfnWndProc = &MyWndProc;
::RegisterClass(&windowClass);
ici, nous déclarons MyWndProc()
comme ayant la convention __stdcall
(CALLBACK
est #define
« d comme __stdcall
). Cela est nécessaire car le système d'exploitation s'attend à ce que lpfnWndProc
pointe vers un WNDPROC
, which uses the CALLBACK
convention.
À peu près toutes les fonctions API de Windows qui accepte un rappel exige que les fonctions de rappel à utiliser la convention __stdcall
, et depuis __cdecl
est généralement la valeur par défaut, vous devez faire ce explicite (vous pouvez utiliser CALLBACK
pour les procédures de la fenêtre).
Ceci est extrêmement important car la corruption de la pile peut se produire si le système d'exploitation tente d'appeler une fonction non __stdcall
. Malheureusement, assez de gens se trompent que Windows will actually check for calling convention mismatch specifically for window procedures. Si __stdcall
est requis pour les fonctions de rappel passées aux fonctions WinAPI, les fonctions acceptant un nombre variable d'arguments doivent utiliser la convention d'appel __cdecl
, car seul l'appelant saura comment retirer correctement le nombre variable d'arguments de la pile. Comme __cdecl
est généralement la valeur par défaut, vous n'avez pas besoin de spécifier explicitement __cdecl
pour les fonctions acceptant un nombre variable d'arguments.
Personnellement, je n'ai pas trouvé une utilisation pour __fastcall
, mais je suis sûr que quelqu'un l'a.
__clrcall
est pertinent uniquement si vous interagissez avec du code managé.