Name Mangling and Function Overloading



The C++ provides a feature called function overloading. This enables you to write many functions with same name, provided each function takes parameters of different types. The lower level languages (C or assembly) and tools (linker) do not have capability of function overload. For these languages, each function name must be unique so that functions can be differentiated from each other by name only.
As the C++ differentiate functions with name and parameter both. It generates a new name for each function. The new name depends on the original C++ function name and parameters. Given a function name of a set of parameter, it will always generate a unique name. If parameters (number of params, type of params or order of params) change then it will generate another name even if the original C++ function name is same. This process of encoding the function name is known as name mangling.
The name mangling is compiler dependent. Each compiler can use different strategies. The name mangled by a compiler may not be same as other compiler.

Here are few examples of mangled name for g++ compiler:-
Original name:   void myFun();      Mangled name:  _Z5myFunv
Original name:  void myFun(int a, char c);      Mangled name:  _Z5myFunic

looking at the mangled name we can observe the pattern. The pattern looks like: -
_Z numberOfCharsInOriginalFunctionName OriginalFunctionName parameter_names_encoded

Parameter encoding scheme:
for primitive type:
char: c
int: i
long: l
void: v
for array or pointer:
P is appended
for user defined type names:
size of the user defined string is appended before the name e.x. for class name myClass, it will be encoded as 7myClass

Lets take few more examples:
void myFun(int a, char *p, int arr[]) ==> _Z5myFuniPcPi
void myFun(int a, MyClass c) ==> _Z5myFuni7MyClass

We have seen all example of functions not part of any class. If a function is part of any class, then the mangling is little different. For example

class MyClass
{
   void MyFunction(int a) {}
}
Here is mangled name of MyClass:MyFunction will become _ZN7MyClass10MyFunctionEi.
Name mangling with namespace:
namespace NS
{
    class myClass
    {
        public: void MyFunction(int a) {}
    };
}
Here mangled name for the function will become _ZN2NS7myClass10MyFunctionEi
Now find out he pattern yourself.
There is gnu tool called c++filt which can take the mangled name and demangles the name. Readers are encouraged to play with this tool and try to demangle all names given in above examples.
The exact pattern of name mangling is not important to programmer. For the programmer the important thing to understand is there is unique method name which is generated for each overload so that it can be resolved (by assembler, linker) without any ambiguity.
 

Interfacing with C

C++ mangles all function name but C does not. What will happen if you are writing mixed-mode code. Some of the source files are compiled by C++ compiler and some files by C compiler and then you link the objects created by these compilers.
Lets take an example: you are writing a library in a file called lib.cpp and consuming this library in another file called use.cpp the content of these files are like-

lib.cpp
int libFunction(int x)
{
    return x++;
}
use.cpp
int libFunction(int x);
int main()
{
    cout<<libFunction(2);
}

compile these two files (by C++ compiler) separately and link. This will work fine. The use.cpp has a unresolved reference to the method "int libFunction(int x)" and this is provided by lib.cpp and unresolved reference gets resolved. As the code is getting compiled by the c++ compiler, there will be name mangling. So the use.cpp has a unresolved reference to a method name _Z11libFunctioni and the lib.cpp file provide the definition of the method _Z11libFunctioni.
Now think what will happen if the lib.cpp file is compiled by c compiler and use.cpp by c++ compiler? The lib.cpp will export a method with name libFunction but the use.cpp has unresolved reference to _Z11libFunctioni. The unresolved reference will not be satisfied and there will be linker error.
There is way to tell c++ compiler that do not mangle the method name which is implemented somewhere else. That means it will not import the method with mangled name. There is a keyword extern which is used for this. After using this keyword the use.cpp will will become:

use.cpp
extern "C" int libFunction(int x);
int main()
{
    cout<<libFunction(2);
}

in this code the imported method name will become libFunction rather than _Z11libFunctioni. So this will work fine if the the lib.cpp is complied with a C compiler.


Writing a header file which can be used by both C and C++ compiler
A typical way of writing C or C++ code is to declare the method names in a header file and include the header file in both files: the consumer of the method name and the implementer of the method. If the one of the file is in C and other in C++ and then the inclusion of header file will result into a compilation error in the C file because extern is not a C keyword. There is a simple solution of using conditional compilation. The header file which contains the libFunction declaration will look like

#ifdef __cplusplus
extern "C" int libFunction(int x);
#else
int libFunction(int x);
#endif

The __cplusplus is only defined for C++. So the declaration with extern keyword will be used only by C++ compiler and the other declaration will be used only by C compiler.

Comments

A more scalable\manageable solution is to define EXTERN_C and use the EXTERN_C macro for all c style functions instead of having two prototypes for each function

#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif

EXTERN_C int libFunction(int x);

I find it even easier to have just this:

#ifdef __cplusplus
extern "C" {
#endif

int libFunction( .. );

#ifdef __cplusplus
};
#endif

I find it even easier to have just this:

#ifdef __cplusplus
extern "C" {
#endif

int libFunction( .. );

#ifdef __cplusplus
};
#endif

Name mangling is compiler specific. which means we cannot expect every compiler to follow the same rule while mangling the name of the functions. thats why we cannot instantiate an object of a class from a library which is compiled using MSVC while using gcc as compiler. since both the compilers use different rules while mangling the names of classes and methods.

There is a tool called "nm" in linux which lists all symbols in a binary file.
For windows there is a tool called dependencywalker which can be downloaded from http://www.dependencywalker.com/ which also does the same.

A name is a word or term used for identification. Names can identify a class or category of things, or a single thing,

either uniquely, or within a given context. You gor more name through this site www.pptse.net

Chell
www.pptse.net
M2M

I'm impressed. You're truly well informed and very intelligent. You wrote something that people could understand and made the subject intriguing for everyone. I'm saving this for future use.

Claire
www.imarksweb.net
Marks Web

This post has been extremely insightful & useful to increase my knowledge in the field of knowledge & its many facets. Well, I'm so happy that I have found this post because I have been seeking some information about it. Here’s a good resource that is also worth a look.

Beth
www.bailerbin.com
Technology Guide

By Viewing this post you can get more information about everything you want. This post can make you lively. It's my pleasure that i found this post because I've always seeking all information i want but through this post I've got everything. This is so good one of your reference.

Alea
www.sppea.org
Information Guide

I like your post a lot! You should write some more on this!Great job coming with such terrific post!

Hello, very well explained. I understood the name mangling now, Thanks a lot for the posting such a nice article. Good job

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.