DEV Community

Lam Nguyen
Lam Nguyen

Posted on

Name Mangling and Type-safe Linkage in C/C++

Alt Text

What is Name Mangling?

Notice that C++ supports function overloading. Therefore, there can be more than one functions with same name and differences in parameters. The question to point out is how the C++ compiler distinguishes between functions when it generates object code. The solution to this problem is that C++ changes name by adding information about arguments. Additional information added to functions is called Name Mangling.

Let's have a look at declarations of function f():
Alt Text
C++ compiler mangle above names to following
Alt Text

Handle C symbols when linking from C++

C does not support function overloading, which names may not be mangled. This is called linking problems. Let's have a look at a C++ program that uses printf() function of C:
Alt Text
In later versions of GCC (GNU Compiler Collection) or the more common MinGW (Minimalist GNU for Windows), which supports both C and C++, no error may be given.

However, an expected error of printf() if compiled in earlier versions of compilers is undefined reference to 'printf(char const*, ...)' ld returned 1 exit status.

The reason for this error is that printf is changed by C++ compiler and it does not find definition of the function with new name.

Luckily, we still have a solution to this problem: extern "C" in C++. Change the above program to following, the program works fine and prints Lam Nguyen on console.
Alt Text
When codes are put in extern "C" block, C++ compiler ensures that the function names are unmangled - that the compiler emits a binary file with their names unchanged, as a C compiler would do.
Notice that because of the "unmangled" property, all C style header files (stdio.h, string.h, .. etc) have their declarations in extern "C" block;

Note: If you can compile the C++ program without having to extern C in C++, let's give a round of applause to the developers of cross-language compiler!

What is Type-safe Linkage

Type-safe linkage enforces the right number and type of parameters are passed at link time.

For example, in C, you can define a library function as taking an int, but through a series of mishaps/accidents, you can pass it as a string.

C++ avoids this kind of error by making function prototypes mandatory and using name mangling to enforce type-safe linking.

Let's look at an example:
Alt Text
Function here is actually f(int), the compiler does not know this because it was told through an explicit declaration - that the function is f(char). In C, the linker would also be successful, but not in C++.

I believe the above information about Type-safe is rather shallow, and require deeper research into the hidden mechanisms of it!

Reference: CPP Forum

Top comments (1)

Collapse
 
pgradot profile image
Pierre Gradot

I am sorry to tell you that the linker doesn't enforce type-safety...

At least with ld (gcc's linker), linking is just about binding symbols, solely based on their names. Prototypes are actually lost at this point of the process.

Thanks to mangling during compilation of each translation unit, symbol's names somehow reflect the prototypes of the functions. Hence mismatches during link edition are quite unlikely.

Nevertheless, you can still you can fool the linker if you want.

Let's take this code as your main.cpp:

void f(const char*);

int main() {
    f("hello, world");
}
Enter fullscreen mode Exit fullscreen mode

You get a linker error: undefined reference tof(char const*)'`.

You can add the options -Xlinker --no-demangle so that the linker shows the mangled name instead. The error becomes: undefined reference to _Z1fPKc'`.

Then you can add this to main.cpp:

extern "C" {
    void _Z1fPKc(int* v) {
        *v = 0;
    }
}
Enter fullscreen mode Exit fullscreen mode

And now the program links successfully : )