【发布时间】:2018-01-03 07:55:15
【问题描述】:
我对 GCC 5.4.0 链接器有一个非常奇怪的问题。我有这些文件:
spline.h,
utils.h/cpp,
main.cpp
spline.h 是一个仅用于将点拟合到样条的实用程序类。
1) 我用 utils.cpp 和 CMake 创建了一个库:
add_library(utils_lib utils.cpp)
utils.h 是 #includeing spline.h。
2) 我从main.cpp 创建我的二进制文件:
add_executable(hello_world main.cpp)
target_link_libraries(hello_world utils_lib)
3)在utils.cpp里面,我有这个功能:
tk::spline fitSpline(const std::vector<double>& x,
const std::vector<double>& y)
{
tk::spline output;
output.set_points(x,y);
return output;
}
所以,如果我尝试在main.cpp 中使用这个函数:
auto my_spline = fitSpline(x,y);
然后我得到这个链接器错误:
undefined reference to `fitSpline(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> > const&)'
但是,如果我将fitSpline 的返回值更改为double,例如:
double fitSpline(const std::vector<double>& x,
const std::vector<double>& y)
{
tk::spline output;
output.set_points(x,y);
return 0.0;
}
然后我不再收到链接器错误!它编译得很好。我真的不明白问题是什么,有什么提示吗?
谢谢!
【问题讨论】:
-
在
utils.h中是否存在fitSpline的函数签名?目前唯一能想到的。可以的话,把相关代码贴在utils.*和main.cpp。 -
@hnefatl 是的,签名在那里。正如我所说,如果我只是更改返回值类型,一切都会正常工作。我刚刚意识到
spline.h的所有内容都在匿名命名空间中,这肯定是原因!那么我需要在每个 cpp 文件中#include吗? -
如果他们真的在anonymous namespace 中,那么文件之外的任何东西都应该无法访问它们。通过签名,我的意思是问您是否有该功能的拆分定义和实现,并且忘记更新其中之一。在
main.cpp中包含spline.h可能会有所帮助,但我真的不知道为什么会这样。发布更多代码会有所帮助。 -
是的,它们在
utils.cpp和utils.h中具有相同的签名。我刚刚在main.cpp、utils.cpp和utils.h中尝试了#includeingspline.h,但它仍然不起作用。仅当我跳过utils并在main.cpp中直接使用spline.h而不是将其包装在函数中时才有效。 -
其实
spline.h开头是: // 未命名的命名空间只是因为实现在这个 // 头文件中,我们不想将符号导出到 obj 文件 namespace { namespace tk { (Sorry对于格式化,我可以在 cmets 部分做正确的代码吗?)
标签: c++ gcc cmake linker undefined-reference