Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the return type of C++ function template instantiations included in the mangled function name?

Tags:

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.)

like image 940
EvanED Avatar asked May 05 '15 15:05

EvanED


People also ask

How do you find the mangled function?

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.

What is function template syntax?

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.


1 Answers

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.

like image 151
Columbo Avatar answered Oct 03 '22 00:10

Columbo