My own experiments show the instantiation of a non-member template function has internal linkage, however the answer to this other post seem to suggest that it has external.
It properly states it somewhere in the standard, but I have a hard time finding it.
My experiment
2 sources files and 1 header:
// source.hpp
#pragma once
#include <iostream>
template<typename T>
void print_size() {
std::cout << "Size: " << sizeof(T) << std::endl;
}
void call_print_size();
// source.cpp
#include "source.hpp"
void call_print_size() {
return print_size<int>();
}
// main.cpp
#include "source.hpp"
int main() {
print_size<int>();
call_print_size();
}
I'm compiling using MSVC from VS2022 Developer Command Prompt:
cl main.cpp source.cpp /std:c++17 /EHsc
If I'm correct, this would create 2 definitions of the int-instantiation of print_size; one in source.cpp and one in main.cpp. I would expect this to break the One-Definition Rule, if they have external linkage - however, it works just fine.
A function template declared without the keyword
staticat namespace scope(and some other conditions see below) have external linkage.From Linkage documentation:
Additionally, from one definition rule:
Basically the linker can discard other definitions and just use any one of them(assuming they are exactly the same).