Question

As far as I know, only the caller-clean-stack convention can use variable arguments.
By the way, the WinApi StringCchPrintfW is declared like this.(I removed the SAL)

__inline HRESULT __stdcall
StringCchPrintfW(
STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, ...
);

Can stdcall have a variable arguments either?

Was it helpful?

Solution

No. The stdcall calling convention has the callee clean the stack. Since the callee is cleaning the stack there is no way for it to know at compile time how much to pop off, therefore it cannot have variable arguments.

In order to have variable number of function arguments you need to use cdecl, which has the caller clean the stack. This all the compiler to determine how many arguments are being passed and since the caller is cleaning up the stack it also knows how much to pop off the stack when the call to the function returns.

In the case mentioned above, the function is declared to use __stdcall, which as previously mentioned does not support variable arguments. In this case, the compiler makes the decision to ignore the calling convention defined and revert back to __cdecl. This behavior is alluded to in the description for stdcall, mentioned above. I quote:

The callee cleans the stack, so the compiler makes vararg functions __cdecl.

This can be observed if the following code is compiled and a call to the function disassembled.

int __stdcall Bar(int a, int b, ...)
{
  return b * a;
}

The resulting code will be treated as __cdecl. As to the reason this is defined that way, I do not know.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top