176

I'm learning about Win32 programming, and the WinMain prototype looks like:

int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )

I was confused as to what this WINAPI identifier was for and found:

#define WINAPI      __stdcall

What does this do? I'm confused by this having something at all after a return type. What is __stdcall for? What does it mean when there is something between the return type and function name?

Andrew Prock
  • 6,900
  • 6
  • 40
  • 60
Tristan Havelick
  • 67,400
  • 20
  • 54
  • 64
  • 2
    @AndrewProck The "dummy" change was okay in this case, but in general you can use ` `s to get around the silly (and counter-productive--case in point) 6 character minimum. – Adi Inbar Jan 10 '14 at 00:01

8 Answers8

203

__stdcall is the calling convention used for the function. This tells the compiler the rules that apply for setting up the stack, pushing arguments and getting a return value.

There are a number of other calling conventions, __cdecl, __thiscall, __fastcall and the wonderfully named __declspec(naked). __stdcall is the standard calling convention for Win32 system calls.

Wikipedia covers the details.

It primarily matters when you are calling a function outside of your code (e.g. an OS API) or the OS is calling you (as is the case here with WinMain). If the compiler doesn't know the correct calling convention then you will likely get very strange crashes as the stack will not be managed correctly.

Jeff Linahan
  • 3,775
  • 5
  • 37
  • 56
Rob Walker
  • 46,588
  • 15
  • 99
  • 136
  • 11
    See this question for an example of very starnge crashes http://stackoverflow.com/questions/696306/run-time-check-failure-0-loading-queryfullprocessimagename-from-kernel32-dll – sharptooth Apr 17 '09 at 04:08
  • 2
    If I'm not mistaken, then these calling conventions control how the compiler produces the assembly code. When interfacing with the assembly code, it is then critical that the calling convention is taken note of to prevent stack issues. There is a nice table here documenting some conventions: https://msdn.microsoft.com/en-us/library/984x0h58.aspx – Nicholas Miller Jul 24 '15 at 17:03
  • Can we say that this would disable certain illegal optimizations ? – kesari Jun 05 '17 at 14:52
47

C or C++ itself do not define those identifiers. They are compiler extensions and stand for certain calling conventions. That determines where to put arguments, in what order, where the called function will find the return address, and so on. For example, __fastcall means that arguments of functions are passed over registers.

The Wikipedia Article provides an overview of the different calling conventions found out there.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
25

The answers so far have covered the details, but if you don't intend to drop down to assembly, then all you have to know is that both the caller and the callee must use the same calling convention, otherwise you'll get bugs that are hard to find.

MovEaxEsp
  • 389
  • 2
  • 3
12

I agree that all the answers so far are correct, but here is the reason. Microsoft's C and C++ compilers provide various calling conventions for (intended) speed of function calls within an application's C and C++ functions. In each case, the caller and callee must agree on which calling convention to use. Now, Windows itself provides functions (APIs), and those have already been compiled, so when you call them you must conform to them. Any calls to Windows APIs, and callbacks from Windows APIs, must use the __stdcall convention.

Windows programmer
  • 7,871
  • 1
  • 22
  • 23
  • 3
    and it must not be confused with _standard_call in that it is standard-c ! one might think that would be the point of __stdcall if one doesnt know better – Johannes Schaub - litb Nov 18 '08 at 02:38
  • 3
    A small nitpick: there are a few Windows APIs that use __cdecl instead of __stdcall - usually ones that take variable number of parameters, such as wsprintf(). – Michael Burr Nov 18 '08 at 08:20
  • You're right. It's named to look like a CRT function but it's an API. By any chance do you know how to P/Invoke it from C#? – Windows programmer Nov 19 '08 at 04:36
  • I haven't tested this, but pinvoke.net gives this signature: "static extern int wsprintf([Out] StringBuilder lpOut, string lpFmt, ...);" – Michael Burr Nov 21 '08 at 04:54
  • My intuition says that the C# compiler wouldn't know to use the __cdecl convention on that one. – Windows programmer Nov 21 '08 at 08:34
10

Have a look at:

http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx

Bakudan
  • 19,134
  • 9
  • 53
  • 73
5

It has to do with how the function is called- basically the order in which things are put on the the stack and who is responsible for cleanup.

Here's the documentation, but it doesn't mean much unless you understand the first part:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
5

__stdcall is used to put the function arguments in the stack. After the completion of the function it automatically deallocates the memory. This is used for fixed arguments.

void __stdcall fnname ( int, int* )
{
    ...
}

int main()
{
    CreateThread ( NULL, 0, fnname, int, int*...... )
}

Here the fnname has args it directly push into the stack.

philippe lhardy
  • 3,096
  • 29
  • 36
1

I never had to use this before until today. Its because in my code I am using multi-threadding and the multi-threading API I am using is the windows one (_beginthreadex).

To start the thread:

_beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0);

The ExecuteCommand function MUST use the __stdcall keyword in the method signature in order for beginthreadex to call it:

unsigned int __stdcall Scene::ExecuteCommand(void* command)
{
    return system(static_cast<char*>(command));
}
Katianie
  • 589
  • 1
  • 9
  • 38