C++ 找不到符号或未定义的符号
大多数在UNIX上工作的人经常会遇到这种令人恼火的错误。 有些时候,解决这个问题需要的时间会少一些,有时会花很多时间 甚至我也经常遇到这种情况,我需要一些关于c/c中具体错误的好文件或文章++ 可能存在符号未找到/未定义符号错误的所有情况是什么C++ 找不到符号或未定义的符号,c++,c,unix,compilation,C++,C,Unix,Compilation,大多数在UNIX上工作的人经常会遇到这种令人恼火的错误。 有些时候,解决这个问题需要的时间会少一些,有时会花很多时间 甚至我也经常遇到这种情况,我需要一些关于c/c中具体错误的好文件或文章++ 可能存在符号未找到/未定义符号错误的所有情况是什么 有谁能帮助我了解这些情况吗?对于大多数情况,当您得到一个未找到/未定义的符号,或者有时甚至出现“重复符号”错误时,它们通常源于链接器无法在您尝试构建的项目中找到符号这一事实 最好的方法是查看生成的映射文件或编译器输出的符号表。它可能看起来像这样: 这将
有谁能帮助我了解这些情况吗?对于大多数情况,当您得到一个未找到/未定义的符号,或者有时甚至出现“重复符号”错误时,它们通常源于链接器无法在您尝试构建的项目中找到符号这一事实 最好的方法是查看生成的映射文件或编译器输出的符号表。它可能看起来像这样: 这将允许您查看符号是否存在。此外,可能还有其他一些深奥的问题,例如编译器优化,这些问题可能会导致符号重复,特别是在内联汇编中。这些是最难发现的 至于好的资源和材料,我没有很多好的参考资料。当我当时四处询问时,大多数高级工程师实际上都从他们自己的经验中学到了东西 但我相信,正是这些论坛帮助我们加快知识获取的速度 希望有帮助:)
干杯 在大多数情况下,当您得到一个未找到/未定义的符号或有时甚至出现“重复符号”错误时,它们通常是由于链接器无法在您试图构建的项目中找到符号 最好的方法是查看生成的映射文件或编译器输出的符号表。它可能看起来像这样: 这将允许您查看符号是否存在。此外,可能还有其他一些深奥的问题,例如编译器优化,这些问题可能会导致符号重复,特别是在内联汇编中。这些是最难发现的 至于好的资源和材料,我没有很多好的参考资料。当我当时四处询问时,大多数高级工程师实际上都从他们自己的经验中学到了东西 但我相信,正是这些论坛帮助我们加快知识获取的速度 希望有帮助:)
干杯 该错误与UNIX/Windows/任何其他操作系统无关,而是与语言本身有关。使用编译器提供的信息进行诊断实际上相当简单。通常他们会告诉你丢失了什么符号,有时还会告诉你在哪里使用。缺少符号的主要原因有:
- 您已声明但从未定义它
- 您已经定义了它,但没有将编译后的符号(对象文件/库)添加到链接器
- 它是外部的,您忘记链接库,或者您正在链接无效的版本,或者以错误的顺序链接
voidfoo(int,double);
,但定义为voidfoo(double,int),那么第一个就有点棘手了
。与所有其他情况一样,编译器将告诉您它要查找的确切签名,确保您已经定义了该符号,而不是接近或类似的符号,如果您在声明和定义中使用不同的调用约定,则特定的角格可能是,因为它们在代码中看起来非常相似
在库外部代码的情况下,复杂性在于识别要添加符号需要链接的库,以及来自库文档的库。请注意,对于静态库,链接器命令行中库的顺序会影响结果
为了帮助您找到实际定义的符号,您可以使用nm
(gcc,在unix系统中很常见)。因此,基本上您可以对正在链接的对象文件/lib运行nm
,并搜索链接器抱怨的符号。这将有助于解决顺序不同的情况(即符号存在,但链接器跳过了它)
运行时(感谢Matthieu M.指出这一点)您可能会遇到与动态库类似的问题,如果在LD_library_路径中发现库的错误版本,您可能会得到一个没有所需符号的库。此错误与UNIX/Windows/任何其他操作系统无关,而是与语言本身有关。使用信息诊断实际上相当简单编译器提供的选项。通常它们会告诉您缺少什么符号,有时会告诉您在哪里使用。缺少符号的主要原因是:
- 您已声明但从未定义它
- 您已经定义了它,但没有将编译后的符号(对象文件/库)添加到链接器
- 它是外部的,您忘记链接库,或者您正在链接无效的版本,或者以错误的顺序链接
voidfoo(int,double);
,但定义为voidfoo(double,int),那么第一个就有点棘手了
。与所有其他情况一样,编译器将告诉您它要查找的确切签名,确保您已经定义了该符号,而不是接近或类似的符号,如果您在声明和定义中使用不同的调用约定,则特定的角格可能是,因为它们在代码中看起来非常相似
在库外部代码的情况下,复杂性在于确定要添加符号需要链接哪些库,这来自库的文档