__cdecl
Microsoft Specific
This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code. The following list shows the implementation of this calling convention.
Element | Implementation |
---|---|
Argument-passing order |
Right to left |
Stack-maintenance responsibility |
Calling function pops the arguments from the stack |
Name-decoration convention |
Underscore character (_) is prefixed to names, except when exporting __cdecl functions that use C linkage. |
Case-translation convention |
No case translation performed |
Note
For related information, see Decorated Names.
On Itanium Processor Family (IPF) and x64 processors, __cdecl is accepted and ignored by the compiler; on IPF, by convention, parameters are passed in register.
Place the __cdecl modifier before a variable or a function name. Because the C naming and calling conventions are the default, the only time you need to use __cdecl is when you have specified the /Gz (stdcall) or /Gr (fastcall) compiler option. The /Gd compiler option forces the __cdecl calling convention.
For non-static class functions, if the function is defined out-of-line, the calling convention modifier does not have to be specified on the out-of-line definition. That is, for class non-static member methods, the calling convention specified during declaration is assumed at the point of definition. Given this class definition,
struct CMyClass {
void __cdecl mymethod();
};
this
void CMyClass::mymethod() { return; }
is equivalent to this
void __cdecl CMyClass::mymethod() { return; }
Example
In the following example, the compiler is instructed to use C naming and calling conventions for the system
function:
// Example of the __cdecl keyword on function
int __cdecl system(const char *);
// Example of the __cdecl keyword on function pointer
typedef BOOL (__cdecl *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);