Learn C++ Itanium Symbol Mangling
Lesson 2: Arguments
All symbols that we have looked at so far have ended with a
v
. I have previously explained that the
v
stands for a function type with no arguments.
C++ has function overloading, which means that a function with the same name can be declared multiple times with different argument types, and the one with matching argument types will be called. If we just mangled the function name as shown previously, this wouldn't work, because we'd get multiple symbols with the same name, which is exactly what mangling is designed to avoid. Therefore, any C++ mangling scheme must encode the function argument types in the symbol name.
void a(int x); void a(char *y); int main() { a(0); // This will call the first a }
The function type is encoded after the name. It contains all the arguments for the function. In some cases it will also contain the return type first, but not for the functions we are looking at right now.
void a(int x, int y, long z) {}
This function will be mangled as _Z1aiil
. We already
know what _Z1a
means, but the iil
is new.
It represents the three arguments, an int
, another
int
, and then a long
. The primitives are
just a single character, more complex types have more characters.
A function taking zero arguments is interpreted as a function taking
(void)
, which is encoded as v
.
int
is i
, long
is
l
. float
is f
,
double
is d
. These types are very easy to
remember, many others less so. Other easy to remember frequently
used types are pointers (T*
) which are encoded as
P
followed by the pointed to type and references
(T&
) which encoded as R
followed by the
referenced type.
void a(int x, int *y, double &z) {}
This function is mangled as _Z1aiPiRd
. It's an
int
(i
), a
int*
(Pi
), and a
double&
(Rd
).
What is the mangled symbol of the following function?
void hello(int **programmer, long day, float &r) {}
We can combine this with our previous knowledge of nested names to mangle the following definition:
namespace outer::inner { void yes(int a, int b, long &c) {} }
This will be mangled as _ZN5outer5inner3yesEiiRl
What is the mangled symbol of the following function?
namespace very::much::nested { void name(int **a, long &raw, float f, double d) {} }
Let's look at a few more common types.
char
is c
. unsigned int
is
j
(like i
but one higher).
unsigned long
is m
, following the same
pattern. long long
(64-bit) is x
(you can
think of it being the native integer, integer x on modern machines)-
unsigned long long
is y
, again being one
higher. short
is s
, with its unsigned
variant being, you may have guessed it, t
.
In the future there might be a part of the website where you can memorize these encodings more easily.
What is the mangled symbol of the following function?
void name(unsigned long long a, unsigned short b, char c, int d) {}
Good job! You have now learnt about the mangling of basic types. In the next lesson, we will use there types as template arguments.