1

When you compile a C source file into an object file, the function names in the object file will be decorated. Each calling convention will have a different decoration.

For example, the following __stdcall function:

void __stdcall stdcallFunction(int i)
{
    int j = 12345;
}

Will be decorated like this in the object file:

_stdcallFunction@4

And the following __cdecl function:

void __cdecl cdeclFunction(int i)
{
    int j = 12345;
}

Will be decorated like this in the object file:

_cdeclFunction

Now my question is, why is name decoration used? I mean why not have the function stdcallFunction be saved in the object file simply as stdcallFunction and not as _stdcallFunction@4?


I think the reason is the following:

Say I created a library (a .lib library and not a .c library) that contains the above two functions.

Now I want to call the function stdcallFunction in this library from my `C source file, I would do the following:

void __stdcall stdcallFunction(int i);

stdcallFunction(123);

This will compile fine. But if I did the following (changed the calling convention for the function declaration):

void __cdecl stdcallFunction(int i);

stdcallFunction(123);

Then this will produce a compilation error.

So the reason for using name decoration is for the compiler to make sure that I am using the correct calling convention when calling a function that exists in a library (the name decoration is simply an indication of what is the calling convention of a function in a library).

Am I correct?

  • the compiler and the linker use the leading underscores. This is NOT function name decoration. Now, C++ actually uses function name decoration, so that (in the source code) multiple functions can have the same name (but different parameter lists) Regarding the leading underscores, that is why user names should not have leading underscores. – user3629249 Aug 12 '17 at 4:07
  • @user3629249: Automatically adding an underscore to all function names is also a form of name decoration. With all C compilers that use this decoration, it is also applied to user-defined functions when they get compiled into object code. – Bart van Ingen Schenau Aug 12 '17 at 12:41
2

Name decorating like this is done to prevent some potentially spectacular failures that could occur with different linking mistakes.

Your examples should not produce compiler errors. They should compile just fine. They should produce linker errors, when it tries to find a cdecl function named stdcallFunction. It can produce that error because the compiler decorates the names for cdecl and stdcall differently. If they didn't decorate them differently, then the linker wouldn't have any information with which to realize that the calling conventions are different.

Failures in calling conventions are really bad news. In cdecl, the caller is expected to clean up the stack, removing all of the arguments it pushed. In stdcall, the callee cleans up the stack, removing the arguments before it returns. If the caller and callee don't agree on the state of the stack when the function returns, all sorts of undefined behaviors can show up. This is the kind of error which can completely obliterate debugging opportunities, because even the debuggers depend on having some sense of what the stack looks like.

This, of course, explains why cdecl only requires a simple name mangling (one underbar), but stdcall needs to add the number of bytes it popped. The caller needs to know exactly what the state of the stack will be when the callee returns.

  • "Your examples should not produce compiler errors. They should compile just fine. They should produce linker errors" Yes you are right, when I said "compilation error" I was thinking of compiling in Visual C++ which compile and link in one go. – user8437463 Aug 11 '17 at 5:34
4

I think your reasoning is correct. If you were to call a function with the wrong calling convention, very bad things can happen at runtime, and this way, such errors are caught during program construction (i.e. linking) rather than at runtime.

C++ is known for name mangling, motivated in part by its support for overloaded functions — a set of functions all with the same name though differing in count or types of parameters — so in the C++ case, it is not just about catching errors in separate compilation but also about supporting overloads with the commonly used object and executable file formats that pre-existed C++.

C does not offer overloading of functions so that is not a motivation for C. However, many C compilers are also C++ compilers, so share some underlying implementation details & capabilities.


However, we should not attribute these behaviors that you are observing to the C Language, but rather specific compilers.

The C language does not specify how names that should appear in object files; it does not have __stdcall and __cdecl — these are (non-standard) extensions by certain implementations.

At best the C Standard requires an implementation to support separate compilation (5.1.1.1) but details of object files and linking are simply not in the standard. An implementation is free to use an arbitrary object file format and/or executable file format, including mangling or decorating identifiers.

The C Standard provides no concept of reflection, or dynamically (at runtime) looking up a function by name in a Dynamic-Link Library (DLL), so there is nothing to break if an implementation decorates names.

Again, at best, the standard defines a notion of external linkage (6.2.2).

In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function.

So, basically as long as the same declaration in one compilation unit is properly equated to the same declaration in another compilation unit, the implementation is legal.

-1

Name decoration allows more than one function with the same name, e.g. with different prototypes (arguments). Without the decorated name, you'd be restricted to either having only one function per symbol or you'd have to find the entry point by ordinal instead of name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.