Why should stream functions be declared as "__cdecl"?

Sample code that shows how to create streams using MFC declares a stream function, both static and __cdecl . Why is the latter required? Boost threads is not bothered by this convention, is it just an anachronism?

For example (MFC):

 static __cdecl UINT MyFunc(LPVOID pParam) { ... } CWinThread* pThread = AfxBeginThread(MyFunc, ...); 

While Boost:

 static void func() { ... } boost::thread t; t.create(&func); 

(the code examples may not be 100% correct, since I am not anywhere near the IDE).

What is the meaning of __cdecl? How does this help in creating threads?

+6
c ++ multithreading boost mfc
source share
5 answers

__ cdecl tells the compiler to use the C calling convention (unlike stdcall, fastcall, or any other calling convention supported by your compiler). I suppose VC ++ uses stdcall by default.

The calling convention affects things such as how arguments are pushed onto the stack (or registered, in the case of fastcall), and who pops the arguments from the stack (called or called).

In the case of Boost. I believe that he uses specialized specialization to determine the appropriate type of function and calling convention.

+4
source share

Take a look at the AfxBeginThread() prototype:

 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 conform to this prototype, including the calling convention.

The __cdecl and __stdcall MSDN __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 function callable, so it does not have the same limitations as MFC.

+4
source share

Because your thread will be called by the execution function that controls it for you, and this function expects it to be that way. Boost designed it differently.

Place a breakpoint at the beginning of your stream function and look at the stack when called, you will see a run function that calls you.

+1
source share
Compilers

C / C ++ by default uses the C-calling convention (first pressing the very first parameter on the stack), which allows you to work with functions with a variable number of arguments like printf.

The Pascal calling convention (aka "fastcall") pushes the leftmost parameter first. This is faster, although it costs you the possibilities of simple variable arguments (I read somewhere they are still possible, although you need to use some tricks).

Due to the speed gained from using the Pascal convention, both Win32 and MacOS APIs use this calling convention by default, except in some cases.

If this function has only one parameter, theoretically using any of the calling conventions would be legal, although the compiler can apply the same calling convention to avoid any problems.

Boost libraries were designed with mobility in mind, so they should be agnostic about which caller agreement a particular compiler uses.

+1
source share

The real answer is related to how windows internally invoke the stream flow procedure, and expects the function to abide by a specific calling convention, which in this case is a WINAPI macro, which, according to my system, is defined as:

 #define WINAPI __stdcall 

This means that the called function is responsible for clearing the stack. The reason boost :: thread is capable of supporting arbitrary functions is because it passes a pointer to the function object used in calling the thread :: create function on CreateThread. The threadproc associated with the thread simply calls operator () on the function object.

The reason MFC requires __cdecl to be related to how it internally calls the passed function to call AfxBeginThread. There is no good reason for this unless they plan to allow the vararg options ...

+1
source share

All Articles