Which calling convention is used for functions exported via .def file?

c, calling-convention, visual-c++

Solution

A .def file does not control the calling convention, it is purely determined by the compiler. If you don't explicitly use __cdecl or __stdcall in the function declaration then it is the compiler's default, so __cdecl. Corner cases are __thiscall for C++ member functions and __clrcall for managed code.

The calling convention also selects the name decoration style, specifically invented to avoid accidents with client code getting it wrong. __cdecl adds a single underscore before the name, __stdcall appends "@n" where n is the size of the stack activation frame. Which protects against a stack imbalance when the client code uses a wrong declaration with a mismatch in type or number of the arguments, a fatal and very hard to diagnose problem with __stdcall. Disabling this decoration with a .def file is actually a bad idea and should only ever be contemplated if the DLL is dynamically loaded with LoadLibrary+GetProcAddress. If you intend to have your DLL used by non C/C++ clients then it usually a good idea to use __stdcall explicitly since that tends to be the default for other language runtimes.

None of this matters for 64-bit code, it blissfully has only one calling convention. Although it looks like Microsoft is about to mess that up by adding the __vectorcall calling convention.

Problem

I'm compiling some third party C code with Visual C++. The source tree contains the following .def file: ``` LIBRARY "ThirdParty.dll" EXPORTS ThirdPartyFunction @1 ``` and there's no explicit calling convention specification (like `__stdcall` or `__cdecl`) near `ThirdPartyFunction()` definition. The Visual C++ project properties (C++ -> Advanced -> Calling convention) is set to `__cdecl (/Gd)`. Which calling convention will be used for the exported function and how do I make sure that it's that convention?

Original source

Related problems