- Microsoft Visual C++ Name Mangling
-
Microsoft Visual C++ Name Mangling is a mangling (decoration) scheme used in Microsoft Visual C++ series of compilers. It provides a way of encoding name and additional information about a function, structure, class or another datatype in order to pass more semantic information from the Microsoft Visual C++ compiler to its linker.
Contents
Overview
The C++ language does not define a standard decoration scheme, so Microsoft Visual C++ uses its own.
Any object code produced by the compiler is usually linked with other pieces of object code by the linker. The linker relies on unique object names for identification but C++ (and many modern programming languages) allows different entities to be named with the same identifier as long as they occupy a different namespace. So names should be mangled by the compiler to make them distinct before reaching the linker. The linker also needs a great deal of information on each program entity. For example, to correctly link a function it needs its name, the number of arguments and their types, and so on.
C++ decoration can become fairly complex (storing information about classes, templates, namespaces, operator overloading, etc.). This section explains the specific manner in which the Microsoft Visual C++ series of compilers mangle symbol names.
Basic Structure
All mangled C++ names start with
?
(question mark). Because all mangled C names start with alphanumeric characters,@
(at-sign) and_
(underscore), C++ names can be distinguished from C names.The structure of mangled names looks like this:
- Prefix
?
- Optional: Prefix
@?
- Qualified name
- Type information (see below)
Function
Type information in function names generally looks like this:
- Access level and function type
- Conditional: CV-class modifier of function, if non-static member function
- Function property
Data
Type information in data names looks like this:
- Access level and storage class
- Data type
- CV-class modifier
Elements
Mangled name contains a lot of elements which will be discussed.
Name
Qualified name consists of the following fragments:
- Basic name: one of: name fragment or special name
- Qualification #1: one of: name fragment, name with template arguments, numbered namespace or back reference
- Qualification #2
- ...
- Terminator
@
Qualification is written in reversed order. For example
myclass::nested::something
becomessomething@nested@myclass@@
.Name Fragment
A fragment of a name is simply represented as the name with trailing
@
.Special Name
Special names are represented as a code with a preceding
?
. Most of special names are constructor, destructor, operator and internal symbol. Below is a table for known codes.Code Meaning with no underline Meaning with preceding underline Meaning with two preceding underlines 0
Constructor operator /= 1
Destructor operator %= 2
operator new operator >>= 3
operator delete operator <<= 4
operator = operator &= 5
operator >> operator |= 6
operator << operator ^= 7
operator ! 'vftable' 8
operator == 'vbtable' 9
operator != 'vcall' A
operator[] 'typeof' 'managed vector constructor iterator' B
operator returntype 'local static guard' 'managed vector destructor iterator' C
operator -> 'string'(Unknown) 'eh vector copy constructor iterator' D
operator * 'vbase destructor' 'eh vector vbase copy constructor iterator' E
operator ++ 'vector deleting destructor' F
operator -- 'default constructor closure' G
operator - 'scalar deleting destructor' H
operator + 'vector constructor iterator' I
operator & 'vector destructor iterator' J
operator ->* 'vector vbase constructor iterator' K
operator / 'virtual displacement map' L
operator % 'eh vector constructor iterator' M
operator < 'eh vector destructor iterator' N
operator <= 'eh vector vbase constructor iterator' O
operator > 'copy constructor closure' P
operator >= 'udt returning' (prefix) Q
operator , Unknown R
operator () RTTI-related code (see below) S
operator ~ 'local vftable' T
operator ^ 'local vftable constructor closure' U
operator | operator new[] V
operator && operator delete[] W
operator || X
operator *= 'placement delete closure' Y
operator += 'placement delete[] closure' Z
operator -= Prefix
_P
is used as?_PX
. Its meaning is unknown.Below are the RTTI-related codes (all starting with
_R
). Some codes have trailing parameters.Code Meaning Trailing Parameters _R0
type 'RTTI Type Descriptor' Data type type. _R1
'RTTI Base Class Descriptor at (a,b,c,d)' Four encoded numbers: a, b, c and d. _R2
'RTTI Base Class Array' None. _R3
'RTTI Class Hierarchy Descriptor' None. _R4
'RTTI Complete Object Locator' None. Name with Template Arguments
Name fragments starting with
?$
have template arguments. This kind of name looks like this:- Prefix
?$
- Name terminated by
@
- Template argument list
For example, we assume the following prototype.
void __cdecl abc<def<int>,void*>::xyz(void);
The name of this function can be obtained by the following process:
abc<def<int>,void*>::xyz xyz@ abc<def<int>,void*> @ xyz@ ?$abc@ def<int> void* @ @ xyz@ ?$abc@ V def<int> @ PAX @ @ xyz@ ?$abc@ V ?$def@H@ @ PAX @ @ xyz@?$abc@V?$def@H@@PAX@@
So the mangled name for this function is
?xyz@?$abc@V?$def@H@@PAX@@YAXXZ
.Nested Name
A name fragment starting with
??
denotes a nested name. This is a name inside a local scope which must be exported. Its structure looks like the following:- Prefix
?
- C++ Mangled name (so starting with
?
again)
For example,
?nested@??func@@YAXXZ@4HA
means variable?nested@@4HA(int nested)
inside?func@@YAXXZ(void __cdecl func(void))
. The UnDecorateSymbolName function returnsint 'void __cdecl func(void)'::nested
for this input.Numbered Namespace
In qualification, a numbered namespace is represented as a preceding
?
and an unsigned number. The UnDecorateSymbolName function returns something like '42
' for this kind of input.Exceptionally, if a numbered namespace starts with
?A
, it becomes an anonymous namespace ('anonymous namespace
').Back Reference
Decimal digits 0 to 9 refer to the first through 10th shown name fragments. Referred name fragments can be normal name fragments or name fragments with template arguments. For example, in
alpha@?1beta@@(beta::'2'::alpha)
, 0 refers toalpha@
, and 1 (not 2) refers tobeta@
.Generally, the back reference table is kept during the entire mangling process. This means you can use a back reference to the function name in the function arguments (which appear after the function name). However, in the template argument list, the back reference table is separately created.
For example, assume
?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@
(std::basic_string<unsigned short, std::char_traits<unsigned short>, std::allocator<unsigned short> >
). Instd::basic_string<...>
, 0 refers tobasic_string@
, 1 refers to?$char_traits@G@
, and 2 refers tostd@
. This relation doesn't change wherever it appears.Encoded Number
In name mangling, sometimes numbers must be represented (e.g. array indices). There are simple rules for this:
0
to9
represents numbers 1 to 10.num@
represents a hexadecimal number, where num consists of hexadecimal digits A (which means 0) to P (15). For exampleBCD@
means number 0x123, or 291 in decimal notation.@
represents the number 0.- If allowed, the prefix
?
represents a minus sign. Note that both?@
and@
represent number 0.
Data Type
The table below shows the various data type and modifiers.
Code Meaning with no underline Meaning with preceding underline ? Type modifier, Template parameter $ Type modifier, Template parameter __w64 (prefix) 0-9 Back reference A Type modifier (reference) B Type modifier (volatile reference) C signed char D char __int8 E unsigned char unsigned __int8 F short __int16 G unsigned short unsigned __int16 H int __int32 I unsigned int unsigned __int32 J long __int64 K unsigned long unsigned __int64 L __int128 M float unsigned __int128 N double bool O long double Array P Type modifier (pointer) Q Type modifier (const pointer) R Type modifier (volatile pointer) S Type modifier (const volatile pointer) T Complex Type (union) U Complex Type (struct) V Complex Type (class) W Enumerate Type (enum) wchar_t X void, Complex Type (coclass) Complex Type (coclass) Y Complex Type (cointerface) Complex Type (cointerface) Z ... (ellipsis) The code
X
representsvoid
when it appears in as a return type or pointer type, otherwise it indicates a cointerface. The codeZ
(meaning ellipsis) appears only at the end of an argument list.Primitive & Extended Type
Primitive types are represented as one character, and extended types are represented as one character with a preceding
_
.Back Reference
Decimal digits
0
to9
refer to the first through 10th shown type in the argument list. (This means return type cannot be a referent.) Back references can refer to any non-primitive type, including an extended type. Of course back references can refer to prefixed types such asPAVblah@@
(class blah *
), but cannot refer to prefixless types — say,Vblah@@
inPAVblah@@
.With back references for names, in a template argument list the back reference table is separately created. The function argument list has no such scoping rule, though it can be confuseing sometimes. For example, assume
P6AXValpha@@Vbeta@@@Z
(void (__cdecl*)(class alpha, class beta)
) is the first shown non-primitive type. Then0
refers toValpha@@
,1
refers toVbeta@@
, and finally2
refers to 'function pointer'.Type Modifier
A type modifier is used to make a pointer or reference. Type modifiers look like this:
- Modifier type
- Optional: Managed C++ property (
$A
for__gc
,$B
for__pin
) - CV-class modifier
- Optional: Array property (not for functions)
- Prefix Y
- Encoded unsigned number of dimensions
- Array indices as encoded unsigned numbers, one for each dimension
- Referred type info (see below)
There are eight types of type modifier:
none const volatile const volatile Pointer P
Q
R
S
Reference A
B
none ?
,$$C
For normal types, referred type info is data type. For functions, it looks like the following. (It depends on the CV-class modifier)
- Conditional: CV-class modifier, if member function
- Function property
Complex Type (union, struct, class, coclass, cointerface)
Complex types look like this:
- Kind of complex type (
T
,U
,V
, ...) - Qualification without a basic name
Enumerated Type (enum)
An enumerated type starts with the prefix
W
. It looks like this:- Prefix
W
- Real type for enum
- Qualification without basic name
The real type for an enum is represented as follows:
Code Corresponding Real Type 0
char 1
unsigned char 2
short 3
unsigned short 4
int (generally normal "enum") 5
unsigned int 6
long 7
unsigned long Array
An array (not pointer to array) starts with the prefix
_O
. It looks like this:- Prefix
_O
- CV-class modifier
- Data type within array
You can use multi-dimensional array like
_OC_OBH
, but only the outermost CV-class modifier is affected. (In this case_OC_OBH
meansint volatile [][]
, notint const [][]
)Template Parameter
Template parameters are used to represent type and non-type template arguments. They can be used only in a template argument list.
The table below is a list of known template parameters. a, b, c represent encoded signed numbers, and x, y, z represent encoded unsigned numbers.
Code Meaning ?x
anonymous type template parameter x ('template-parameter-x') $0a
integer value a $2ab
real value a × 10b-k+1, where k is number of decimal digits of a $Da
anonymous type template parameter a ('template-parametera') $Fab
2-tuple {a,b} (unknown) $Gabc
3-tuple {a,b,c} (unknown) $Hx
(unknown) $Ixy
(unknown) $Jxyz
(unknown) $Qa
anonymous non-type template parameter a ('non-type-template-parametera') Argument List
An argument list is a sequence of data types. The list can be one of the following:
X
(meansvoid
, also terminating list)- arg1 arg2 ... argN
@
(meaning a normal list of data types. Note that N can be zero) - arg1 arg2 ... argN
Z
(meaning a list with trailing ellipsis)
Template Argument List
A template argument list is the same as an argument list, except that template parameters can be used.
CV-class Modifier
The following table shows CV-class modifiers.
Variable Function none const volatile const volatile none A
B
,J
C
,G
,K
D
,H
,L
6
,7
__based() M
N
O
P
_A
,_B
Member Q
,U
,Y
R
,V
,Z
S
,W
,0
T
,X
,1
8
,9
__based() Member 2
3
4
5
_C
,_D
CV-class modifier can have zero or more prefix:
Prefix Meaning E
type __ptr64 F
__unaligned type I
type __restrict Modifiers have trailing parameters as follows:
- Conditional: Qualification without basic name, if member
- Conditional: CV-class modifier of function, if member function
- Conditional: __based() property, if used
A CV-class modifier is usually used in reference/pointer types, but it is also used in other places with some restrictions:
- Modifier of function: can only have const, volatile attribute, optionally with prefixes.
- Modifier of data: cannot have function property.
__based() Property
__based() property represents Microsoft's __based() attribute extension to C++. This property can be one of the following:
0
(means__based(void)
)2
name (means__based(name)
, where name is a qualification without a basic name)5
(means no__based()
)
Function Property
A function property represents the prototype of a function. It looks like this:
- Calling convention of function
- Data type of returned value, or
@
forvoid
- Argument list
- throw() attribute
The following table shows calling conventions of functions:
Code Exported? Calling Convention A
No __cdecl B
Yes __cdecl C
No __pascal D
Yes __pascal E
No __thiscall F
Yes __thiscall G
No __stdcall H
Yes __stdcall I
No __fastcall J
Yes __fastcall K
No none L
Yes none M
No __clrcall The argument list for the
throw()
attribute is the same as any other argument list, but if this list isZ
, it means there is nothrow()
attribute. If you want to representthrow()
you have to use@
to terminate the list.Function
Typical type information in a function name looks like this:
- Optional: Prefix
_
(means __based() property is used) - Access level and function type
- Conditional: __based() property, if used
- Conditional: adjustor property (as encoded unsigned number), if thunk function
- Conditional: CV-class modifier of function, if non-static member function
- Function property
The table below shows codes for access level and function type:
none static virtual thunk private: A
,B
C
,D
E
,F
G
,H
protected: I
,J
K
,L
M
,N
O
,P
public: Q
,R
S
,T
U
,V
W
,X
none Y
,Z
This kind of thunk function is always virtual, and used to represent the logical
this
adjustor property, which means an offset to the truethis
value in some multiple inheritance situations.Data
Type information in a data name looks like this:
- Access level
- Data type
- CV-class modifier
The table below shows codes for access level:
Code Meaning 0 Private static member 1 Protected static member 2 Public static member 3 Normal variable 4 Normal variable The CV-class modifier should be appropriate for data (not a 'function' modifier).
Thunk Function
There are several kinds of thunk function.
See also
- Programming language
- Microsoft Visual C++
- Name mangling
- C++
References
- Kang Seonghoon. "Microsoft C++ Name Mangling Scheme". http://mearie.org/documents/mscmangle. Retrieved 2008-10-05.
External links
- Microsoft C++ Name Mangling Scheme
- C++ Name Mangling/Demangling
- Geoff Chappell's results
- __unDname Wine's __unDname function implementation
- PHP UnDecorateSymbolName A PHP Script that demangles Microsoft C++ Names by Timo Stripf
- Undname Convert a decorated name to its undecorated form
Categories: - Prefix
Wikimedia Foundation. 2010.