C++ Name Mangling Explained: Symbols, extern "C", and Linking
이 글의 핵심
Compilers encode names with type and scope information (name mangling). Understanding it helps with linking, extern "C", and mixed C/C++ projects.
What is name mangling?
The compiler turns function and variable names into unique symbol names that encode types, namespaces, and parameter lists. This matters for linking and ABI compatibility.
From the linker’s perspective, each symbol in the final binary is a single string. In C, short names like func suffice. In C++, several overloads can share the name func, so the compiler encodes “name + type information” into strings like _Z... in .o symbol tables.
Below, both declarations use the identifier func in source, but the linker sees different symbols.
// Source: both named "func"
void func(int x) {}
void func(double x) {}
// Roughly on GCC/Clang (Itanium ABI); details may vary by environment.
// _Z4funci → "func" + (int)
// _Z4funcd → "func" + (double)
//
// _Z : Itanium mangling prefix
// 4func : length 4 + name func
// i, d : argument type encodings (int, double)
nm on an object file may show _Z-prefixed lines. Pipe through c++filt for human-readable demangling (func(int), func(double)).
Why it is needed
// Overloading: the compiler picks which print() at the call site
void print(int x) {}
void print(double x) {}
void print(const std::string& x) {}
// At link time each definition must have a distinct mangled name.
Namespaces, class members, and template instantiations add more “name space,” so mangling encodes extra information. That keeps A::f vs B::f and vector<int>::size vs vector<double>::size distinct.
Practical examples
Example 1: Inspect symbols
# Compile
g++ -c program.cpp
# Symbols
nm program.o
# Demangle
nm program.o | c++filt
Example 2: extern “C”
// C++ mangling
void func(int x) {}
// symbol: _Z4funci
// C linkage (no C++ mangling)
extern "C" void func(int x) {}
// symbol: func
// C library headers
extern "C" {
#include <stdio.h>
}
Example 3: C++ library callable from C
// mylib.h
#ifdef __cplusplus
extern "C" {
#endif
void my_function(int x);
#ifdef __cplusplus
}
#endif
// mylib.cpp
extern "C" void my_function(int x) {
std::cout << x << std::endl;
}
Example 4: Fixing link errors
// ❌ C function compiled as C, declared as C++ in another TU
void c_function(); // expects mangled name
// main.cpp
c_function(); // link error
// ✅ extern "C"
extern "C" void c_function();
int main() {
c_function(); // OK
}
Mangling examples
// Namespace
namespace MyLib {
void func() {}
}
// _ZN5MyLib4funcEv
// Class member
class MyClass {
void func() {}
};
// _ZN7MyClass4funcEv
// Template
template<typename T>
void func(T x) {}
// func<int>: _Z4funcIiEvT_
Common issues
Issue 1: Link errors across C and C++
// mylib.c
void my_func() {}
// main.cpp
void my_func(); // C++ expects mangled symbol
my_func(); // link error
// ✅ extern "C"
extern "C" void my_func();
Issue 2: Header guards with C linkage
// myheader.h
#ifdef __cplusplus
extern "C" {
#endif
void c_function();
#ifdef __cplusplus
}
#endif
Issue 3: Overloading with extern “C”
// ❌ extern "C" cannot overload
extern "C" {
void func(int x);
// void func(double x); // error
}
// ✅ Different C names
extern "C" {
void func_int(int x);
void func_double(double x);
}
Issue 4: Compiler differences
# GCC/Clang often follow Itanium C++ ABI mangling.
# MSVC uses different rules.
# Mixing .o/.obj from incompatible toolchains can break linking.
#
# In practice: use one compiler (and compatible ABI) per project.
Demangling
# c++filt
echo "_Z4funci" | c++filt
# func(int)
# With nm
nm program.o | c++filt
# objdump
objdump -t program.o | c++filt
FAQ
Q1: Why name mangling?
A:
- Overloading
- Namespace disambiguation
- Type-safe linking
Q2: When is extern “C” used?
A:
- Calling C libraries
- Exposing C++ to C
- Plugin systems with C APIs
Q3: Demangling?
A: Use the c++filt tool.
Q4: Compiler differences?
A: Rules differ; Itanium ABI is common on GCC/Clang.
Q5: Why no overloading in extern “C”?
A: No mangling, so names must be unique.
Q6: Further reading?
A:
- Linkers and Loaders
- Itanium ABI documentation
- GCC documentation
Related: Linking, ABI, extern linkage, compilation process.
Related posts (internal links)
- C++ Linking
- C++ Extern Linkage
- C++ Compilation Process
Practical tips
Debugging
- Check compiler warnings first.
- Reproduce with a minimal case.
Performance
- Profile before micro-optimizing.
- Define metrics.
Code review
- Anticipate common review comments.
- Follow conventions.
Practical checklist
Before coding
- Right technique?
- Maintainable?
- Performance OK?
While coding
- Warnings cleared?
- Edge cases?
- Errors handled?
During review
- Clear intent?
- Enough tests?
- Documented?
Keywords (search)
C++, name mangling, linking, overloading, ABI
Related posts
- C++ Compilation Process
- C++ Function Overloading
- C++ Linking
- C++ One Definition Rule
- Arrays and lists (algorithms)