Historically, the first C ++ compilers used the __stdcall equivalent. In terms of implementation quality, I would expect the C compiler to use the __cdecl __cdecl and the C ++ __stdcall (which were then called Pascal loops). This is one that the early Zortech compilations got it right.
Of course, vararg functions should still use __cdecl . callle cannot clear the stack if it does not know how much to clear.
(Note that the C standard was carefully designed to __stdcall in C. I know of only one compiler that took advantage of this, however; the amount of existing code at that time calling vararg functions without a prototype was huge, and although the standard declared that it is broken, the compiler developers do not want to break the code of their clients.)
In many conditions, there seems to be a very strong tendency to insist that the C and C ++ conventions are the same, that you can take the address of the extern "C++" function and pass it to a function written in C that calls it. IIRC, for example, g ++ does not apply
extern "C" void f();
and
void f();
as having two different types (although the standard requires this), and allows you to pass the address of a static member function to pthread_create , for example. As a result, such compilers use all the same conventions, and on Intel, they are the equivalent of __cdecl .
Many compilers have extensions to support other loops. (Why they don’t use the standard extern "xxx" , I don’t know.) The syntax for however these extensions is very diverse. Microsoft adds an attribute immediately before the function name:
void __stdcall func( int, int );
g ++ puts it in a special attribute clause after the Declaration function:
void func( int, int ) __attribute__((stdcall));
C ++ 11 adds a standard way to specify attributes:
void [[stdcall]] func( int, int );
It does not specify stdcall as an attribute, but it does indicate that additional attributes (other than those defined in the standard) can and are implementation dependent. I expect both g ++ and VC ++ to adopt this syntax in their latest versions, at least if C ++ 11 is activated. The exact name of the attribute ( __stdcall , stdcall , etc.) can change, so you probably want to wrap this with a macro.
Finally: in a modern compiler with optimizations enabled, the difference in calling conventions is probably negligible. Attributes like const (not to be confused with the C ++ const keyword), regparm or noreturn are likely to have a greater impact, both in terms of executable file size and performance.