Why are function names decorated in C

c

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?

Best Answer

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.

Related Topic