I'm observing this peculiar phenomenon in which g++ will not export the template function instantiations if they're only used inlined.. This is not true for regular non-templated functions, of course. For example:
// main.cpp
#include <iostream>
#include "inc.h"
int main() {
std::cout << func<3>() << std::endl;
std::cout << func2() << std::endl;
return 0;
}
// inc.h
template<int num>
int func();
int func2();
// a.cpp
template<int num>
int func() {
return num;
}
int func2() {
return 5;
}
int result;
int result2;
void instantiate() {
// store the results in globally visible variables
// so the compiler won't optimize them out completely
result = func<3>();
result2 = func2();
}
If I compile the above with -O0
, linking is successful - objdump
confirms the binary code for both func2
and func<3>
is generated in a.o
and instantiate
is making two function calls, ie the functions are not being inlined.
However, -O3
changes things - instantiate
contains no function calls and func<3>
is not generated in the assembly, causing a linker error. func2
is still there, of course.
I was bitten by this in real code, expecting the functions to be exported and getting linker errors. Is this behavior expected? Could the compiler be convinced to generate the functions even if they're only used inline in the compilation unit they're implemented in? In my case we have many template specializations.. explicit instantiation would be impractical.