c 链接编译器错误

问题描述 投票:0回答:2

这是我从

gcc
调用中得到的错误:

gcc -o rr4 shells2.c graph1.c rng.c;

  Undefined symbols:  
   "_getdisc", referenced from:  
       _main in cckR7zjP.o  
  ld: symbol(s) not found

每次调用编译器时,“cckR7zjP.o”都会不断变化。 该方法的代码在文件

graph1.c
中;它的头文件称为
graph2.h
,我将其导入到具有名为
shells2.c
的主要方法的文件中,使用:

#include "graph2.h"

方法或函数定义为:

int getdisc(int i){ return disc[i];}

尝试返回由 创建的阵列光盘的第 ith

成员
static int *disc;  

我已经用其他方法初始化了!我认为有问题的电话是:

for (iter = 0; iter < n; iter++) {
    if (getdisc(iter) == cln)
        avgbtwn += get_betweenness(iter);
}

这似乎是一个链接器问题,我检查了一些其他问题,我认为我正确链接了我的方法(并且在代码中的其他地方使用相同的方法),但我仍然无法弄清楚这一点。

编辑:所以我将linux中命令的顺序切换为

gcc -o rr4 graph1.c rng.c shells2.c   

按照Soren的建议并且函数编译正常,有人知道为什么吗? 此外,当我在文件 graph1.c 中添加尾随换行符时,似乎可以缓解问题。

c gcc extern
2个回答
2
投票

旧的 GCC 2.x 编译器/链接器曾经存在一个问题,即当符号未组合在一起时链接器无法解析链接——可以认为链接器只会查找仍然需要的符号,并且它会丢弃未使用的符号。

对于大多数人来说,这个问题会表现为库的排序问题(用 -l 或 .a 指定)。

我从评论中看到你使用的是Mac,所以可能只是Mac版本的编译器/链接器仍然存在这个问题——无论如何,因为重新排序源文件解决了问题,那么你肯定有一些变化这个错误。

可能的解决方案;

  1. 将所有源文件分组为更大的文件——不好的解决方案——但链接器不太可能因这种症状而失败——或者
  2. 尝试首先将所有文件编译为 .o,然后链接 .o 文件(通常使用 makefile 可以做到这一点,但可能会也可能不会解决问题)并可能将 .o 合并为单个 .a (man ar ), 或
  3. 更改源文件的顺序,使 shell2.c 最后出现(这对您有用),或者
  4. 看看升级编译器是否有帮助

很抱歉列出了很长的清单,但这显然只是一个编译器错误,只需要一个简单的解决方法即可。


2
投票

这绝对是一个错误,链接器看不到

getdisc
,但是,如果你说的是正确的,那不应该发生。

您拥有的

gcc
命令行包括
graph1.c
,您保证使用它包含该功能。

不用担心目标文件名,这只是编译器创建的临时名称,用于传递给链接器。

您能否确认(精确剪切和粘贴)您正在使用的

gcc
命令行,并向我们展示函数定义及其周围的一些上下文?

此外,通过在

graph1.c
函数之前插入以下行,确保
getdisc
按预期编译:

xyzzy plugh twisty;

如果编译器正在识别您的函数,那么首先应该会导致错误。它可能类似于 ifdef

 语句,导致您的代码无法编译。

通过测试,以下记录显示您正在

尝试做的事情效果很好:

pax> cat shells2.c #include "graph2.h" int main (void) { int x = getdisc (); return x; } pax> cat graph2.h int getdisc (void); pax> cat graph1.c int getdisc (void) { return 42; } pax> gcc -o rr4 shells2.c graph1.c pax> ./rr4 pax> echo $? 42

因此,我们必须假设您

实际上正在做的事情是不同的,这对我来说非常机智:-)

您所经历的是类似以下情况会发生的情况:

pax> gcc -o rr4 shells2.c /tmp/ccb4ZOpG.o: In function `main': shells2.c:(.text+0xa): undefined reference to `getdisc' collect2: ld returned 1 exit status

或者如果

getdisc

graph1.c没有
正确声明。

最后一种情况可能有多种原因,包括但不限于:

  • getdisc
    拼写错误。
  • #ifdef
    类型语句意味着从未见过定义(尽管您似乎在评论中忽略了这一点)。
  • 有些人使用
  • #define
    getdisc
     更改为其他内容(不太可能,但有可能)。
© www.soinside.com 2019 - 2024. All rights reserved.