ham*_*els 6 c++ openmp undefined-reference
g++ -fopenmp main.cpp抱怨未定义的引用std::vector.如何解决这个问题?
我libomp-dev在Ubuntu上安装了这个包.
main.cpp中
#include<vector>
#include<iostream>
template<typename T, typename A>
T recursiveSumBody(std::vector<T, A> &vec) {
T sum = 0;
#pragma omp task shared(sum)
{
sum = recursiveSumBody(vec);
}
return vec[0];
}
int main() {
std::vector<int> a;
recursiveSumBody(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
未定义的参考文献
/tmp/ccTDECNm.o: In function `int recursiveSumBody<int, std::allocator<int> >(std::vector<int, std::allocator<int> >&) [clone ._omp_cpyfn.1]':
main.cpp:(.text+0x148): undefined reference to `std::vector<int, std::allocator<int> >::vector(std::vector<int, std::allocator<int> > const&)'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您可以手动指定shared(sum, vec)(强烈假设您希望它共享)。
有趣的是,较旧的 gcc 版本(例如 5.4.0)给出了更有用的错误消息:
error: 'vec' implicitly determined as 'firstprivate' has reference type
Run Code Online (Sandbox Code Playgroud)
而英特尔编译器icpc 17.0.1给出了一个“ internal error : 0_1855”。
手动指定firstprivateor private- 这在您的情况下意义不大 - 会导致其他更具描述性的错误。请注意,正如 Hristo Iliev 在其他评论中所解释的那样,firstprivate这意味着为每个线程制作向量的副本。
根据当前 (4.5) 标准:
在孤立任务生成构造中,如果不存在默认子句,则通过引用传递的正式参数为
firstprivate。
我想这适用于这里。更远,
出现在
firstprivate子句中的变量不得具有不完整的 C/C++ 类型或对不完整类型的引用。如果firstprivate工作共享构造子句中的列表项具有引用类型,则它必须绑定到团队所有线程的同一对象。
它没有出现在条款中,但我认为这仍然是标准的意思。
现在我不认为这std::vector<T, A>是模板中的不完整类型,除非我遗漏了一些关于模板如何实例化的信息。所以我确实认为你的代码应该是有效的,并且考虑到每个线程都绑定到同一个对象,它实际上是有意义的。
所以我确实认为这是最近gcc版本以及英特尔编译器中的一个错误。看起来编译器无法为模板实例化一些东西。
进一步补充:
if (0) std::vector<T, A> wtf = vec;
Run Code Online (Sandbox Code Playgroud)
在函数的开头使代码编译并与gcc. 但是如果firstprivate是手动添加,gcc 会继续抱怨'vec' has incomplete type.
PS:OpenMP 4.5 中添加了允许数据共享属性子句中的引用类型,这是旧的 gcc 给出了不同的错误。
| 归档时间: |
|
| 查看次数: |
721 次 |
| 最近记录: |