What is happening in this WinMain() declaration? - c++

I am learning about C++ and programming to the windows api. My first "Hello Windows API" program just displays a MessageBox(). But, I have questions that the book I'm reading isn't explaining.
First, here's the program:
// HelloWin32 Program
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MessageBox(NULL, "This gets displayed in the message.", "This is the title bar of the message dialog.", MB_OK | MB_ICONEXCLAMATION);
}
This compiles and runs fine. My question has to do with the WinMain() declaration that says int WINAPI WinMain(...). As I read it, the WinMain function (method?) returns an integer. But what does WINAPI communicate?
Obviously, I'm writing to the Windows API. Does WINAPI somehow flag the function so the program uses Windows API to execute it or something?

WINAPI is a preprocessor definition defined as __stdcall, a calling convention; when functions have __stdcall before their name, it is a directive to the compiler to make the function use that calling convention. This is so both your function and the function calling your function agree to use the stdcall calling convention and the call executes correctly.
This is necessary because the default calling convention of your compiler may or may not be stdcall, so you have to explicitly tell the compiler to make it that way for that function. The designers of the Windows API decided, mainly for compatibility reasons and the universality of the stdcall calling convention, to make all function calls use the stdcall calling convention.
Also, you can have functions with different calling conventions being used in the same program. So for instance, WinMain has to be stdcall but the other functions of your program do not; they can use the compiler default.
A calling convention is a method for doing things like the order in which parameters should go on the stack, who should remove them from the stack when the function returns, where to put return values, and other things. Different calling conventions do this in different ways. Above all, it is extremely important that both the caller and the callee follow the same calling convention. For more info on calling conventions, see the Wikipedia article.

Related

What is better to declare for calling convention of Windows program?

I have read an article about Calling convention (__stdcall, __fastcall, pascal, cdecl etc...)
And I wonder: Why is often __stdcall (WinAPI) declared for WinMain() function?
As I read, __stdcall operates with the stack, __fastcall operates on registers and not using stack at all.
So , I've tried to declare WinMain() with the __fastcall. Compiler (Visual C++) has given me an error.
error C2373: 'WinMain' : redefinition; different type modifiers
c:\program files\microsoft sdks\windows\v6.0a\include\winbase.h(2560) : see declaration of 'WinMain'
Why can't I use __fastcall for WinMain() and is there any possibility to use it for it?
Because to work on registers without using stack is miles faster, isn't it?
PS
My suggestion is, that there are some method contracts that disallow me to use __fastcall, but it's only my suggestion.
You can only specify the calling convention on functions that you write and/or you have the source code of.
You cannot change calling conventions of function that are in a library (static/dynamic) since those are already compiled/linked.
Important is that the declaration and definition have the same convention.
BTW : you wouldn't gain anything by having (win-)main having the fastcall convention since it's only called once!
You would consider fastcall on functions with many small parameters (that fit in registers) that are called very very often during long periodes of time.
The (buildin) startup routine for windows programs will call either WinMain or main (depending on GUI or Console app) with a specific convention.
If you write a WinMain or main with a different convention then the linker will complain.
WinMain must be __stdcall. It's called by the CRT start-up code, which is already built to pass parameters in a way defined by __stdcall convention.

Is preceding a function with CALLBACK or WINAPI or PASCAL (in MFC) is absolutely necessary or only for readability purpose?

In MFC VC++, setTimer function is setted using a CALLBACK procedure. From the link I read that
A function that is marked with __stdcall uses the standard calling
convention so named because all Win32 API functions (except the few
that take variable arguments) use it.
And from that, this is what I have understand, ALL THE VC++ MFC FUNCTIONS USE __stdcall as their calling conversions.
And CALLBACK is defined as follows....
#define CALLBACK __stdcall
What I have read:
Preceding a function with CALLBACK is used to emphasise that the particular function will be called automatically whenever necessary(like in this setTimer case or onClick case in javascript),
My doubt is , In MFC VC++ all functions(except the few
that take variable arguments) has a default calling convention of __stdcall. Hence either preceding or not preceding a function with CALLBACK or WINAPI or PASCAL has a same effect?
Is it absolutely necessary for the computer? It depends on the context. When you mismatch the calling convention, you could either get lucky because the datatypes on the stack happen to match the requirements of the API, or it could fail miserably when your code is run on a different architecture like x64 and crashes every time.
Is it absolutely necessary for the maintenance programmer? Yes, it is. You know, the poor person who will have to figure out your non-standard conventions and clever "optimizations." Some day, that poor person might be you.
The compiler was yelling at you for a reason when you tried to subvert the API.

What is the point of defining a calling convention?

For example:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
WINAPI is a a define that looks like this:
#define WINAPI __stdcall
why can't you just do:
int __stdcall WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
actually I think my problem is that I'm sort of confusing defines with typedef's. Can someone explain this to me? what does the define do and why can't you just write __stdcall in its place?
Because the WINAPI calling convention is not guaranteed to be __stdcall. Code that uses WINAPI will still be correct even when it isn't.
You can write the function as in your latter example, and it'd work fine - it's just not good practice and would not be portable to a platform where the calling convention is something else.
This was originally done during the switchover from 16-bit to 32-bit code. In the 16-bit version of <windows.h> it was:
#define WINAPI __pascal
WINAPI let you compile for either without modifying the source code. Of course, 16-bit Windows is no longer a factor (at least for most people), but it's still not worth changing all the source code to use __stdcall directly (especially since it could change again someday).
You can just write __stdcall in its place, but don't. They've seen fit to #define WINAPI to __stdcall to make that opaque, which is just good programming practice.
Also, back in the day, some Windows libraries used Pascal calling convention and other libraries used C convention. A preprocessor define helped gloss over that.
Because WINAPI is a macro (well a #define anyway) it can be "pre-processed" to mean something else or even nothing at all.
That means you can write more portable code, as you can put in WINAPI when it is required by Win32 to mean __stdcall but, or if it is required in another environment to mean something else or nothing.

What does "WINAPI" in main function mean?

Could you please explain to me the WINAPI word in the WinMain() function?
In the simplest way..
#include <windows.h>
int -->WINAPI<-- WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);
return 0;
}
Is it just some Windows funky mode?
What does it do? Or rather what is this C++ feature I haven't encountered yet?
WINAPI is a macro that evaluates to __stdcall, a Microsoft-specific keyword that specifies a calling convention where the callee cleans the stack. The function's caller and callee need to agree on a calling convention to avoid corrupting the stack.
WINAPI is a macro that expands to __stdcall which means that the callee cleans the stack.
This is a macro definition intended to denote the Windows calling convention. From MSDN:
The way the name is decorated depends
on the language and how the compiler
is instructed to make the function
available, that is, the calling
convention. The standard inter-process
calling convention for Windows used by
DLLs is known as the WinAPI
convention. It is defined in Windows
header files as WINAPI, which is in
turn defined using the Win32
declarator __stdcall.
It's Windows-specific. It specifies the calling convention. WinMain gets called by Windows, and this ensures that the caller and callee agree on the calling convention.

Why do thread functions need to be declared as '__cdecl'?

Sample code that shows how to create threads using MFC declares the thread function as both static and __cdecl. Why is the latter required? Boost threads don't bother with this convention, so is it just an anachronism?
For example (MFC):
static __cdecl UINT MyFunc(LPVOID pParam)
{
...
}
CWinThread* pThread = AfxBeginThread(MyFunc, ...);
Whereas Boost:
static void func()
{
...
}
boost::thread t;
t.create(&func);
(the code samples might not be 100% correct as I am nowhere near an IDE).
What is the point of __cdecl? How does it help when creating threads?
__cdecl tells the compiler to use the C calling convention (as opposed to the stdcall, fastcall or whatever other calling convention your compiler supports). I believe, VC++ uses stdcall by default.
The calling convention affects things such as how arguments are pushed onto the stack (or registers, in the case of fastcall) and who pops arguments off the stack (caller or callee).
In the case of Boost. I believe it uses template specialization to figure out the appropriate function type and calling convention.
Look at the prototype for AfxBeginThread():
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
AFX_THREADPROC is a typedef for UINT(AFX_CDECL*)(LPVOID). When you pass a function to AfxBeginThread(), it must match that prototype, including the calling convention.
The MSDN pages on __cdecl and __stdcall (as well as __fastcall and __thiscall) explain the pros and cons of each calling convention.
The boost::thread constructor uses templates to allow you to pass a function pointer or callable function object, so it doesn't have the same restrictions as MFC.
Because your thread is going to be called by a runtime function that manages this for you, and that function expects it to be that way. Boost designed it a different way.
Put a breakpoint at the start of your thread function and look at the stack when it gets called, you'll see the runtime function that calls you.
C/C++ compilers by default use the C calling convention (pushing rightmost param first on the stack) for it allows working with functions with variable argument number as printf.
The Pascal calling convention (aka "fastcall") pushes leftmost param first. This is quicker though costs you the possibility of easy variable argument functions (I read somewhere they're still possible, though you need to use some tricks).
Due to the speed resulting from using the Pascal convention, both Win32 and MacOS APIs by default use that calling convention, except in certain cases.
If that function has only one param, in theory using either calling convention would be legal, though the compiler may enforce the same calling convention is used to avoid any problem.
The boost libraries were designed with an eye on portability, so they should be agnostic as to which caller convention a particular compiler is using.
The real answer has to do with how windows internally calls the thread proc routine, and it is expecting the function to abide by a specific calling convention, which in this case is a macro, WINAPI, which according to my system is defined as:
#define WINAPI __stdcall
This means that the called function is responsible for cleaning up the stack. The reason why boost::thread is able to support arbitrary functions is that it passes a pointer to the function object used in the call to thread::create function to CreateThread. The threadproc associated with the thread simply calls operator() on the function object.
The reason MFC requires __cdecl therefore has to do with the way it internally calls the function passed in to the call to AfxBeginThread. There is no good reason to do this unless they were planning on allowing vararg parameters...