how template instantiation doesn't lead to linking error

Viewed 157

I know that the following code will result in a linking error:

//first.cpp
void test(){
    //random code
}

//second.cpp
void test(){
    //random code
}

so lets say that we have this function template:

template<typename T>
T test(){
    //random code
}

and are doing this:

//first.cpp
...
test<void>();

//second.cpp
...
test<void>();

so the way I understand how compiler works is that it only cares for each file individually so it only cares that test<void>() must have a definition therefore it will create one. same thing goes for the second.cpp then why don't we get an linker error at later stage when there are two definitions for test<void>.(I think this should be same as the first example where those two void test() functions in separate files lead to a linking error)

if this is a duplicate I'm sorry I literally didn't know how to search for this.

2 Answers

The linker doesn't complain because the standard says so:

[basic.def.odr]/13

There can be more than one definition of a
...
— inline function or variable ...

— templated entity ...

In this regard, the linker handles them as if they were inline.

Note that they're not actually inline (for the purposes of optimizations). You can mark them as inline yourself, hinting the compiler that they should be inlined.

Try it with inline

//first.cpp
inline void test(){
    //random code
}

//second.cpp
inline void test(){
    //random code
}

This tells the linker not to worry about multiple definitions of that function in multiple translation units. Templates have this without adding inline.

Related