2

使用 g++ 并出现链接器错误。我有一个简单的程序,分为两个模块:main.cpp 和 Dice.h Dice.cpp。

主.cpp:

#include <iostream>
#include "Dice.h"

int main(int argc, char **argv) {

    int dieRoll = Dice::roll(6);
    std::cout<<dieRoll<<std::endl;

    std::cin.get();

    return 0;
}

骰子.h:

#ifndef DieH
#define DieH

namespace Dice
{
    int roll(unsigned int dieSize);
}

#endif

骰子.cpp:

#include <ctime>
#include <cstdlib>
#include "Dice.h"

namespace Dice
{
    int roll(unsigned int dieSize)
    {
        if (dieSize == 0)
        {
            return 0;
        }
        srand((unsigned)time(0));
        int random_int = 0;
        random_int = rand()%dieSize+1;

        return random_int;
    }
}

我使用 g++ 编译和链接这些文件,如下所示:

g++ -o program main.cpp Dice.cpp

我收到以下链接器错误:

Undefined symbols:
"Dice::roll(int)", referenced from:
  _main in ccYArhzP.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

我完全糊涂了。任何帮助将不胜感激。

4

3 回答 3

9

您的代码格式正确。

确保您没有冲突的文件名,这些文件存在并包含您认为它们所做的事情。例如,也许你有一个Dice.cpp空的,而你正在其他地方编辑一个新创建的。

通过删除不必要的文件来最小化可能的差异;只有main.cpp,dice.hdice.cpp.

您的错误与您的代码不匹配:"Dice::roll(int)". 请注意,这正在寻找一个int,但您的函数需要一个unsigned int. 确保您的标题匹配。


尝试以下操作:

g++ main.cpp -c

这将为main.omain 生成已编译但未链接的代码。做同样的事情dice.cpp

g++ dice.cpp -c

您现在有两个需要链接在一起的目标文件。这样做:

g++ main.o dice.o

看看这是否有效。如果没有,请执行以下操作:

nm main.o dice.o

这将列出对象中的所有可用符号,并且应该为您提供如下内容:

main.o:
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 t .text
00000098 t __GLOBAL__I_main
00000069 t __Z41__static_initialization_and_destruction_0ii
         U __ZN4Dice4rollEj
         U __ZNSi3getEv
         U __ZNSolsEPFRSoS_E
         U __ZNSolsEi
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
         U __ZSt3cin
         U __ZSt4cout
         U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b __ZStL8__ioinit
         U ___gxx_personality_v0
         U ___main
00000055 t ___tcf_0
         U _atexit
00000000 T _main

dice.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T __ZN4Dice4rollEj
         U _rand
         U _srand
         U _time

C++ 会破坏函数名称,这就是为什么一切看起来都如此怪异的原因。(注意,没有标准的修改名称的方法,这就是 GCC 4.4 的做法)。

请注意dice.omain.o引用相同的符号:__ZN4Dice4rollEj。如果这些不匹配,那就是你的问题。例如,如果我将部分更改为dice.cpp

// Note, it is an int, not unsigned int
int roll(int dieSize)

然后nm main.o dice.o产生以下内容:

main.o:
00000000 b .bss
00000000 d .ctors
00000000 d .data
00000000 r .eh_frame
00000000 t .text
00000098 t __GLOBAL__I_main
00000069 t __Z41__static_initialization_and_destruction_0ii
         U __ZN4Dice4rollEj
         U __ZNSi3getEv
         U __ZNSolsEPFRSoS_E
         U __ZNSolsEi
         U __ZNSt8ios_base4InitC1Ev
         U __ZNSt8ios_base4InitD1Ev
         U __ZSt3cin
         U __ZSt4cout
         U __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
00000000 b __ZStL8__ioinit
         U ___gxx_personality_v0
         U ___main
00000055 t ___tcf_0
         U _atexit
00000000 T _main

dice.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T __ZN4Dice4rollEi
         U _rand
         U _srand
         U _time

请注意,这给出了两个不同的符号。main.o寻找 this:__ZN4Dice4rollEjdice.o包含 this __ZN4Dice4rollEi。(最后一个字母不同)。

当试图编译这些不匹配的符号(带g++ main.o dice.o)时,我得到:

undefined reference to `Dice::roll(unsigned int)'
于 2009-11-03T04:42:33.267 回答
1

您的问题是您正在调用Dice::roll(int)并且您编写了一个Dice::roll(unsigned int)函数。它正在寻找的函数实际上并不存在(在内部,函数的参数类型与其名称一样重要;这就是重载的工作方式)。尝试将它传递给 unsigned int (6u例如),看看它是否有效。或者,您的头文件可能在两个文件中都不匹配,并且 main.cpp 认为您的函数采用(有符号的)int。

于 2009-11-03T04:39:15.113 回答
0

我知道你不想听到这样的声音,但是“它对我有用!”。

您的错误看起来很旧 - 您使用的是什么版本的 GCC?这看起来像 GCC 2.x!此外,尝试在 main.cpp 中将 dieRoll 键入为 unsigned,这可能会解决这个旧编译器上的命名空间问题。

于 2009-11-03T04:41:55.093 回答