Archived

This topic is now archived and is closed to further replies.

__cdecl vs __stdcall vs __thiscall

This topic is 5807 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What exactly do they do? I know that regular functions are by default __cdecl. WOrrds like WINAPI and CALLBACK are covers for __stdcall. Class members are __thiscall(i think). But whta exactly do these specify? Im told that __stdcall means args are passed in right-to-left order, versus left-to-right for __cdecl. That means nothing to me. Explain in detail please. ----------------------------- The sad thing about artificial intelligence is that it lacks artifice and therefore intelligence.

Share this post


Link to post
Share on other sites
Function calling conventions affect two different things

1) how parameters are pushed onto the stack ( right to left or left to right )

which is void Func(int i, char j);

left to right or vice versa controls which addresses on the stack will contain which variables

2) part is ''who cleans up the stack''

which is caller vs callee -

there is another type __fastcall which specifies that some parameters are passed in registers - but that one is more rare

Share this post


Link to post
Share on other sites
As well as what SteveC said, another difference is in how the names get decorated/mangled in the object code. An underscore is prepended with __cdecl, and a scheme using @ symbols to describe parameters happens when you use __stdcall and __thiscall.

__thiscall simply means that the "this" pointer of a C++ class is passed to the function. (Because member functions of classes get boiled down by the compiler into plain functions with decorated names to differentiate. The linker doesn''t care about language and nicities like overloaded and virtual functions - it just links "uniquely named functions").

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
quote:
Original post by S1CA
As well as what SteveC said, another difference is in how the names get decorated/mangled in the object code. An underscore is prepended with __cdecl, and a scheme using @ symbols to describe parameters happens when you use __stdcall and __thiscall.


I believe this is compiler-dependent; Borland C++ builder likes to do things the other way around, which is why (annoyingly) it exports stdcall DLL functions with an underscore whether you like it or not. (Often leading me to hack the file by hand to get the right function names )



[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites
Kylotan:

Yup, it is implementation dependent. What I wrote was the case for MSVC. The mangling is so the linker gets unique names - its a bit silly in a way that output for linker operation for C++ wasn''t made part of a standard.

[Then again people seem to "interpret" standards in slightly different ways - I''ve had some fun recently making a colleagues MSVC C++ code compile properly with Pro-DG (GameCube) due to differences in the handling of the greyer areas of the C++ standard (explicit keyword, nameless structures inside unions etc]


As for DLLs, I always use .DEF files to ensure non-mangled exports. Although I use MSVC for all PC stuff, mangled exports in DLLs really annoy me.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
S1CA: the "_" is prepended to all symbols in C, regardless of "call type". this is not compiler dependant.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you want to avoid the name mangling of functions exported from DLLs you should either (a) use a DEF file, or (b) declare them as extern "C".

Share this post


Link to post
Share on other sites
Kylotan: that''s because all "C" symbols are prepended with the underscore regardless of call type. check the C spec.

To the vast majority of mankind, nothing is more agreeable than to escape the need for mental exertion... To most people, nothing is more troublesome than the effort of thinking.

Share this post


Link to post
Share on other sites