gcc/ld:对未使用函数的未定义引用

gcc/ld:对未使用函数的未定义引用,gcc,cygwin,ld,Gcc,Cygwin,Ld,我在Windows7下的Cygwin中使用GCC4.3.4和LD2.20.51。以下是我的问题的简化版本: foo.o包含函数foo\u bar(),该函数在bar.o中调用bar() bar.o包含函数bar() main.c调用foo.o中的函数,但是foo\u bar()不在调用链中 如果我试图编译main.c并将其链接到foo.o,我会从ld得到一个对_foo_bar的未定义引用。从我的Makefile中可以看到,除了下面,我已经尝试使用标志将每个函数放入自己的节中,并让链接器丢弃未

我在Windows7下的Cygwin中使用GCC4.3.4和LD2.20.51。以下是我的问题的简化版本:

  • foo.o
    包含函数
    foo\u bar()
    ,该函数在bar.o中调用
    bar()
  • bar.o
    包含函数
    bar()
  • main.c
    调用
    foo.o
    中的函数,但是
    foo\u bar()
    不在调用链中
如果我试图编译main.c并将其链接到foo.o,我会从ld得到一个对_foo_bar的
未定义引用。从我的Makefile中可以看到,除了下面,我已经尝试使用标志将每个函数放入自己的节中,并让链接器丢弃未使用的节

COMPILE_CYGWIN = gcc -iquote$(INCDIR)
COMPILE = $(COMPILE_CYGWIN) -g -MMD -MP -Wall -ffunction-sections -Wl,-gc-sections $(DEFINE)
main_OBJECTS = main.o foo.o
main.exe : $(main_OBJECTS)
    $(COMPILE) -o main.exe $(main_OBJECTS)
函数
foo_bar()
是一个短函数,用于在协议堆栈中的两个网络层之间提供连接。有些程序不需要它,因此它们不会链接到与堆栈上层相关的其他对象文件。这是一个小函数,似乎不适合将其放入自己的.o文件中

我不明白为什么ld会抛出错误——没有任何东西在调用
foo\u bar()
,因此没有必要在最终的可执行文件中包含
bar()
。一位同事刚刚告诉我,
ld
不是一个“智能链接器”,所以可能我正在尝试做的事情是不可能的?

除非链接器来自它,否则它无法确切知道实际将调用哪些函数。它只知道引用了哪些。即使链接器也无法预测将做出什么运行时决策,或者如果您在运行时动态加载模块,并且模块开始调用各种全局函数,将会发生什么情况1

所以,如果你在模块m中链接,它引用函数f,你将需要链接任何有f的模块



一,。此问题与相关,并已得到验证。

我遇到了类似的问题,我发现此页面: 高亮度: GNU链接器仍然在.o文件粒度下工作。 Gcc拉入foo.o,然后find bar()未定义


您最好将foo_bar()放在另一个.o文件中。

-f编译
foo
时需要函数部分。针对
bar
的链接是否也存在任何特殊问题?在这种情况下,在
bar.o
中链接至少需要15个以上的对象文件来填充其依赖项。我想我已经到了需要将目标文件链接到一个库中并让我的程序引用它的地步。除非你有其他限制,否则它并不像听起来那么糟糕。这是一个有点前期痛苦,但它不会有任何显着的运行时成本。我不知道Windows上的动态链接器是如何工作的,但假设它有一半的性能,那么这些无关的代码无论如何也不会被加载。