c++ - g++ 说引用未定义,即使 `nm` 在我的目标文件中列出了符号定义

标签 c++ linker g++

当我正在处理的项目的 Makefile 命中此行时:

g++ -g build_complex.o simplex.o simplex_src.o split.o permutation_src.o permutation_parity.o tropmod.o main.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L/usr/lib/sagemath/local/lib/ -ligraph -lm -o cpptest

我收到以下错误:

main.o: In function `main':
/home/xander/Desktop/tropicalmoduli/main.cpp:5: undefined reference to `(anonymous namespace)::ConfigSpace::ConfigSpace(int, int)'
/home/xander/Desktop/tropicalmoduli/main.cpp:9: undefined reference to `(anonymous namespace)::PermWrapper::PermWrapper(permutation*)'
/home/xander/Desktop/tropicalmoduli/main.cpp:11: undefined reference to `(anonymous namespace)::ConfigSpace::getTraceOfPerm((anonymous namespace)::PermWrapper)'
collect2: error: ld returned 1 exit status

这些是在文件 tropmod.cpp 中定义的函数,该文件被编译为 tropmod.o。当我运行 nm tropmod.o 时吐出:

                 U __cxa_atexit
                 U __dso_handle
                 U free
                 U _GLOBAL_OFFSET_TABLE_
000000000000037c t _GLOBAL__sub_I_tropmod.cpp
                 U igraph_destroy
                 U malloc
                 U _Z10split_freeP5split
                 U _Z12simplex_freeP7simplex
                 U _Z13simplex_traceP7simplexP11permutation
                 U _Z14get_1_skeletoniiPPP5split
                 U _Z16get_mid_skeletoniiiPiPP5splitP8igraph_s
0000000000000333 t _Z41__static_initialization_and_destruction_0ii
00000000000001f0 t _ZN12_GLOBAL__N_111ConfigSpace14getTraceOfPermENS_11PermWrapperE
000000000000010c t _ZN12_GLOBAL__N_111ConfigSpace7destroyEv
0000000000000000 t _ZN12_GLOBAL__N_111ConfigSpaceC2Eii
0000000000000322 t _ZN12_GLOBAL__N_111PermWrapper14getPermutationEv
0000000000000304 t _ZN12_GLOBAL__N_111PermWrapperC2EP11permutation
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
0000000000000000 b _ZStL8__ioinit

所有“ undefined reference ”都列在这里,带有“t”,这应该意味着它们在这个目标文件中定义。 tropmod.o 和 main.o 都是从包含头文件 tropmod.hpp 的 .cpp 文件编译而来,可以在其中找到声明:

#include <iostream>
#include <string>
#include "build_complex.h"

#ifdef tmboost
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>
typedef boost::python::list bplist;
#endif

namespace {

    // allows a permutation to be converted from python::boost::list
    // to permutation* just once, and then reused
    class PermWrapper {
        permutation *perm;

        public:
        #ifdef tmboost 
        PermWrapper(bplist);
        #endif
        PermWrapper(permutation*);

        permutation *getPermutation();
    };

    class ConfigSpace {
        int n,d;
        int *num_cells;
        int num_facets;
        split **all_splits;
        simplex ***skels;

        public:
        ConfigSpace(int n, int d);

        void destroy();

        int getTraceOfPerm(PermWrapper perm);
    };
}

为了完整起见,这里是main.cpp:

#include "tropmod.hpp"

int main() {

    ConfigSpace cs = ConfigSpace(2, 2);

    int p_d[4] = {1, 0, 3, 2};
    permutation *p = perm_alloc_data(4, p_d);
    PermWrapper pw = PermWrapper(p);

    printf("trace: %i\n", cs.getTraceOfPerm(pw));
}

两个 cpp 文件都是用 g++ -g -fPIC -c 编译的(没有 tmboost 标志)。

我在这里查看了有关此类链接错误的其他几个问题,但我阅读的答案显然都不适用于此处。似乎所有的部分都在那里,有没有人知道为什么链接器不能把它们放在一起?

最佳答案

在 C++ 中,anonymous namespaces are local to their translation unit , 它们不能被其他翻译单元引用。

如果您阅读nm 的文档,它清楚地指出小写字母指定局部符号类型。

如果这些是全局符号,它们将被标记为“T”,而不是“t”。

关于c++ - g++ 说引用未定义,即使 `nm` 在我的目标文件中列出了符号定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40187244/

相关文章:

c++ - 指针和双向链表

c++ - 传递包含 const 内容的 vector

时间:2019-03-08 标签:c++libconfigambiguousoverload

c++ - std :shared_ptr in libstdc++ correct 的原子交换是怎样的

c++ - 库适用于 Clang 但不适用于 GCC

c++ - 在 Ubuntu 20.04 中为 RPI4 链接 WiringPi 共享对象库

c++ - 如何在C++中实现模板类协变?

c++ - 无法添加静态库

c - 如何使数据库大小超过 256 字节 [链接器文件 - MPLAB]

c - mips 组装问题