The Itanium ABI specifies that, with a couple uninteresting exceptions, the return type is included in the mangled names of template instantions but not non-templates.
Why is this? In what case could you have two function template instantiations where the linker needs to distinguish them because it is not indicative of a one-definition-rule violation or similar?
As an example of what I mean:
class ReturnType {};
class ParamType {};
template <typename T>
ReturnType foo(T p) {
return ReturnType();
};
template ReturnType foo<ParamType>(ParamType);
ReturnType bar(ParamType p) {
return ReturnType();
}
Then the resulting object file has manglings:
ReturnType foo<ParamType>(ParamType)
=> _Z3fooI9ParamTypeE10ReturnTypeT_
^^^^^^^^^^^^
ReturnType bar(ParamType)
=> _Z3bar9ParamType
Why does foo
need ReturnType
mangled but bar
doesn't?
(I am presuming there is a reason and it's not just an arbitrary choice.)
Well what you can do is compile your C++ program using g++ and get the .o file. Run the 'nm' command on the .o file thus obtained to get the mangled names! This method is viable on Linux systems.
Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
Maybe because, as opposed to normal functions, a function templates signature contains the return type? §1.3:
1.3.17 signature
<
function>
name, parameter type list (8.3.5), and enclosing namespace (if any)
[ Note: Signatures are used as a basis for name mangling and linking. — end note ]
1.3.18 signature<
function template>
name, parameter type list (8.3.5), enclosing namespace (if any), return type, and template parameter list
Consider that we can have two entirely distinct function template overloads that only differ in their return type, if written thusly:
template <int>
char foo();
template <int>
int foo();
If name mangling wouldn't consider the return type, linking those templates would prove difficult, since foo<0>
does not uniquely name one specialization. Still, one specialization can be addressed using overload resolution (without arguments):
int (*funptr)() = foo<0>;
On the other hand, including the return type is not necessary for ordinary functions, as these cannot be overloaded on their return type - i.e. their signature does not include the return type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With