C++ Name Mangling in GCC, Clang, and MSVC

Name mangling is the technique C++ compilers use to encode function signatures, namespaces, classes, and type information into unique symbol names to support language features like function overloading and templates. While the C++ standard defines how the language behaves, it does not standardize the Application Binary Interface (ABI) or name mangling schemes. As a result, GCC, Clang, and MSVC implement different conventions. GCC and Clang primarily share the Itanium C++ ABI standard on non-Windows systems, whereas MSVC uses a proprietary ABI, creating distinct mangling patterns and binary incompatibilities across different toolchains.

The Purpose of Name Mangling

In C, a function named calculate simply produces the linker symbol calculate (or _calculate). Because C does not support function overloading, names are unique.

C++ allows multiple functions with the same name to coexist if their parameter lists differ. It also supports namespaces, class member functions, and template instantiations. To differentiate these functions at the object-code level, compilers transform identifiers into unique strings that encapsulate the full signature, return types, access qualifiers, and scopes.

GCC and Clang: The Itanium C++ ABI

On Linux, macOS, and most Unix-like platforms, both GCC and Clang adhere to the Itanium C++ ABI. Because they share this specification, object files compiled with GCC and Clang on these systems can often interoperate seamlessly.

Mangling Structure in the Itanium ABI

  • Prefix: Mangled symbols typically start with _Z.
  • Namespaces and Classes: Nested scopes are enclosed between N and E. Each identifier is preceded by its character length (e.g., 3Foo for Foo).
  • Basic Types: Built-in types are represented by single letters or short codes:
    • v = void
    • i = int
    • d = double
    • b = bool
    • c = char
  • Modifiers: Pointers are prefixed with P, references with R, and const qualifiers with K.

Example

Consider the following function:

namespace Geometry {
    void drawCircle(int radius, double scale);
}

Under the Itanium ABI (GCC and Clang):

  • Mangled symbol: _ZN8Geometry10drawCircleEid
  • Breakdown:
    • _Z: Mangling prefix.
    • N ... E: Nested scope indicator.
    • 8Geometry: Namespace name with length 8.
    • 10drawCircle: Function name with length 10.
    • v (implicit return type is omitted for normal functions).
    • i: First argument (int).
    • d: Second argument (double).

MSVC: Microsoft's Proprietary ABI

Microsoft Visual C++ (MSVC) uses a proprietary mangling scheme designed specifically for Windows. Unlike the Itanium ABI, MSVC encodes the calling convention and return types directly into the function signature, even for non-template functions.

Mangling Structure in the MSVC ABI

  • Prefix: Mangled symbols generally start with ?.
  • Scope Termination: Scopes and function names are listed in reverse order and separated or terminated by @ symbols. A double @@ marks the end of the qualified name.
  • Calling Convention & Access: Specific characters denote member function visibility (public, private, protected), virtual status, and calling conventions (such as __cdecl, __stdcall, or __thiscall).
  • Basic Types: Types use distinct characters terminated where necessary:
    • X = void
    • H = int
    • N = double
    • _N = bool
    • D = char
  • Modifiers: P indicates a pointer, while modifiers like B denote const.

Example

For the same function:

namespace Geometry {
    void drawCircle(int radius, double scale);
}

Under MSVC (assuming __cdecl):

  • Mangled symbol: ?drawCircle@Geometry@@YAXHN@Z
  • Breakdown:
    • ?: Mangling prefix.
    • drawCircle@Geometry@@: Qualified path (function name first, then namespace, terminated by @@).
    • Y: Specifies non-member function (__cdecl).
    • A: Default storage class/return type modifier.
    • X: Return type (void).
    • H: First argument (int).
    • N: Second argument (double).
    • @Z: End of parameter list.

Clang's Dual-ABI Flexibility

Clang is designed to be ABI-compatible with the native platform compiler:

  • On Linux/macOS: Clang defaults to the Itanium C++ ABI, matching GCC.
  • On Windows: When using the clang-cl driver or targeting the MSVC environment, Clang adopts the MSVC ABI and produces Microsoft-compatible mangled symbols. This allows Clang to link directly against MSVC-generated libraries and the Microsoft C Runtime (CRT).

Side-by-Side Comparison

Feature GCC / Clang (Itanium ABI) MSVC (Microsoft ABI)
Leading Prefix _Z ?
Scope Ordering Left-to-right (8Geometry10drawCircle) Right-to-left (drawCircle@Geometry@@)
String Delimiters Length prefixes (e.g., 8, 10) @ terminators
int Representation i H
double Representation d N
void Return Representation Omitted for regular functions Encoded (X)
Calling Convention Generally omitted from symbol Explicitly encoded

Demangling Tools

To translate these symbols back into readable C++ signatures, developers rely on platform-specific utilities:

  • GCC / Clang (Itanium): The c++filt command-line tool, or the runtime API abi::__cxa_demangle.
  • MSVC: The undname.exe utility, the Windows API function UnDecorateSymbolName, or the DbgHelp library.