Demystifying C++ - Name Mangling

From emmtrix Wiki
Jump to navigation Jump to search


One of the key features of C++ is "Name Mangling" [1]. Although it may seem like a peripheral detail at first glance, it is a fundamental element that enables several core functionalities of C++. Name Mangling is the process by which the C++ compiler modifies the names of variables, functions, and other entities to ensure uniqueness and specific information about these entities. This concept becomes particularly important when considering function overloading, namespaces, class hierarchies, and templates - features not natively present in C.

The process of Name Mangling ensures that each element is uniquely identifiable, even if it appears identical in C++ source code syntax. This is crucial for the linker, which must allocate the correct functions and variables across different files and libraries. As a result, developers often encounter mangled names within object files. Tools like c++filt or websites can be used to demangle these names back into readable elements.

The C++ standard does not prescribe a specific method for Name Mangling. This means that the implementation of Name Mangling is left to the discretion of the compiler manufacturer, leading to differences in Mangling conventions between different compilers. The Itanium C++ ABI, for instance, establishes Name Mangling conventions and is commonly used on Unix-based systems.

The keyword extern "C" can be used to disable Name Mangling for functions in C++. This facilitates interoperability between C++ and C, among other things.

Examples of Name Mangling:

Feature C++ Code C Code
Overloading
void func1(char, short, int, long)
void func2(int, int&,  int&&, int*);
void _Z5func1csil(char, short, int, long);
void _Z5func2iRiOiPi(int, int *, int *, int *);
Namespace
namespace ns1 {
  void func1();
}
void _ZN3ns15func1Ev(void);
Class
class c1 {
  static void func1();
};
static void _ZN2c15func1Ev(void);
Special Functions
void* operator new(size_t s);
void operator delete(void*);
bool operator < (c1, c1);
void * _Znwm(size_t s);
void _ZdlPv(void *ptr);
bool _Zlt2c1S_(struct c1, struct c1);
External Statements
extern "C" void func1();
void func2();
void func1(void);
void _Z5func2v(void);
Template Functions
template<typename T>
void func() { /* ... */ }

template void func<int>();
template void func<float>();
void _Z4funcIiEvv(void);
void _Z4funcIfEvv(void);

For simplicity, the C++ names of the functions will be used throughout the following paper, even if it results in technically incorrect C code.