__cdecl vs __stdcall vs __thiscall

Started by
10 comments, last by Promit 22 years, 2 months ago
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.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Advertisement
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
When i first saw this thread i thought "pepsi vs. coke vs. water".

~don

"They that can give up essential liberty to obtain temporary safety deserve neither liberty nor safety."
- Benjamin Franklin
www.ChippedDagger.com"They that can give up essential liberty to obtain temporary safety deserve neither." -- Benjamin Franklin"If opportunity doesn't knock, build a door." -- Milton Berle
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

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

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 ]
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

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

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.
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.
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".
Anonymous: the extern "C" specifier doesn''t make any difference to Borland - it still shoves an underscore at the start no matter what.
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.
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.

This topic is closed to new replies.

Advertisement