with the following minimal example i get a linker error on my local system in visual studio 15.8.7 (standard console app with standard settings (just removed precompiled headers)): "Error LNK1179 invalid or corrupt file: duplicate COMDAT '??$f@H@@YAXH@Z'"
#include <cstdio>
template<typename T> void f(T) { printf("1"); } //#1. T can be deduced
template<typename T> void f(int) { printf("2"); } // #2. T needs to be specified explicitly
int main()
{
f(8); // a) calls #1
f<int>(8); // b) calls #2
}
- Commenting out either the call a) or call b) will result in successfully linking. Standalone call a) calls template definition #1. The second call b) calls template definition #2. As expected.
- Building in Release mode succeeds. Output is 11. So both calls call template definition #1. Unexpected. ODR-violoation?
- Additionally i observed the following strange behaviour (in debug settings):
- i comment out template definition #2
- i do a full rebuild
- i comment back in template definition #2
- i build (not rebuild, just build)
- build succeeds
- output is 11 instead of 12
Incremental linking doing strange things?
On wandbox, godbolt and coliru i can compile,link and run and get the expected behaviour with gcc and clang.
The observations described in bullet point 3 made me think it has to do with incremental linking. But maybe the code is also just not well defined? When studying https://en.cppreference.com/w/cpp/language/function_template i encountered the following:
Two expressions involving template parameters are called functionally equivalent if they are not equivalent, but for any given set of template arguments, the evaluation of the two expressions results in the same value.
and
If a program contains declarations of function templates that are functionally equivalent but not equivalent, the program is ill-formed; no diagnostic is required.
So, is the above code ill formed? Do i have an ODR-violation? Or is everything fine and its just a linker/compiler bug?
edit: fixed point 3. i comment back in definition #2 or course.
Update: New day, problems solved i guess. Today i can not reproduce the problem. I did not change anything on my system. I just booted up, opened my project and it worked like expected. Dont know whats going on. But its better this way compared to learn new special arcane template overloading rules :-P