- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I get following linking errors when trying to compile simple test program with ICX which calls templatized class from a static library.
main.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl TestLib<float>::TestLib<float>(void)" (??0?$TestLib@M@@QEAA@XZ) referenced in function main
main.cpp.obj : error LNK2019: unresolved external symbol "public: void __cdecl TestLib<float>::print(void)" (?print@?$TestLib@M@@QEAAXXZ) referenced in function main
TemplateProject.exe : fatal error LNK1120: 2 unresolved externals
Here is the CMakeLists.txt of the test project:
cmake_minimum_required(VERSION 3.20)
project(TemplateProject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(TestLib STATIC TestLib.h TestLib.cpp)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC TestLib )
TestLib.h
// TestLib.h
#include <iostream>
template <class RealType>
class TestLib {
public:
TestLib();
void print();
};
TestLib.cpp
// TestLib.cpp
#include "TestLib.h"
template class TestLib<float>;
template class TestLib<double>;
template <class RealType>
TestLib<RealType>::TestLib() {}
template <class RealType>
void TestLib<RealType>::print() {
RealType i{0};
std::cout << "Hallo from the print function! " << i << "\n";
}
and the main.cpp
// main.cpp
#include "TestLib.h"
int main() {
TestLib<float> a;
a.print();
return 0;
};
Having explicit explicit template instantiation is a common practice when having function definitions in .cpp files, and this piece of code works just fine with MSVC 16 compiler as well as with GCC 9.
I tested this on Windows using :
Intel(R) oneAPI DPC++/C++ Compiler for applications running on Intel(R) 64, Version 2021.4.0 Build 20210924
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try to rearrange test.cpp. Basically put template class explicit instantiations below anything else.
https://en.cppreference.com/w/cpp/language/class_template
template <class RealType>
TestLib<RealType>::TestLib() {}
template <class RealType>
void TestLib<RealType>::print() {
RealType i{0};
std::cout << "Hallo from the print function! " << i << "\n";
}
template class TestLib<float>;
template class TestLib<double>;
Thanks,
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for reaching out to us.
We are also able to reproduce the issue from our end.
We are working on it. We will get back to you soon.
Meanwhile, you can try compiling your code with icl compiler.
Thanks & Regards,
Noorjahan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try to rearrange test.cpp. Basically put template class explicit instantiations below anything else.
https://en.cppreference.com/w/cpp/language/class_template
template <class RealType>
TestLib<RealType>::TestLib() {}
template <class RealType>
void TestLib<RealType>::print() {
RealType i{0};
std::cout << "Hallo from the print function! " << i << "\n";
}
template class TestLib<float>;
template class TestLib<double>;
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot! This trick did the work. However shouldn't this be still labeled as compiler bug? Standard does not require specialization to be at the end of the cpp file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
This issue also occurs with LLVM compiler as well. Let me work with our Front End team and get back to you when I have an update.
Thanks,
Viet
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
This is not a compiler bug. C++ is parsed from top to bottom and at the moment when you instantiate your template in the .CPP, the only definition the compiler sees is the one in the header. So your instantiation cannot instantiate the template yet.
Furthermore when instantiating a template somewhere you should declare that in the header:
extern template class TestLib<float>;
Otherwise it would be "reinstantiated" without your specialisation somewhere else and you would break the One Definition Rule.
Best,
Michel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After some discussion in community we realized Clang’s behavior is correct per spec. There is an ABI incompatibility with the other compilers, but fixing that requires an ABI break and given the trivial workaround of defining the class before instantiating it, so there’s almost no chance the ABI break is worth it.
We will close this case as wont fix.
Thanks,
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page