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()
:
C++ compiler
mangle above names to following
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
:
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.
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:
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)
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
:You get a linker error:
undefined reference to
f(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
:And now the program links successfully : )