【问题标题】:gcc/ld: undefined reference to unused functiongcc/ld:对未使用函数的未定义引用
【发布时间】:2011-04-11 17:46:39
【问题描述】:

我在 Windows 7 下的 Cygwin 中使用 gcc 4.3.4 和 ld 2.20.51。这是我的问题的简化版本:

  • foo.o 包含函数 foo_bar() 在 bar.o 中调用 bar()
  • bar.o 包含函数 bar()
  • main.c 调用 foo.o 中的函数,但 foo_bar() 不在调用链中

如果我尝试编译 main.c 并将其链接到 foo.o,我会从 ld 收到 undefined reference to _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_bar(),因此无需在最终可执行文件中包含 bar()。一位同事刚刚告诉我 ld 不是“智能链接器”,所以也许我想做的事情是不可能的?

【问题讨论】:

  • -ffunction-sections 在编译 foo 时需要。与bar 链接也有什么特别的问题吗?
  • 在这种情况下,bar.o 中的链接需要至少 15 个以上的目标文件来填充其依赖项。我想我已经到了需要将目标文件链接到库中并让我的程序引用它的地步。
  • 除非您有其他限制,否则它并没有听起来那么糟糕。这有点前期痛苦,但不会有任何显着的运行时间成本。我不知道 Windows 上的动态链接器是如何工作的,但假设它还不错,那么无论如何都不会加载无关代码。

标签: gcc cygwin ld


【解决方案1】:

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

所以,如果你链接到模块m并且它引用了函数f,你需要链接任何有的模块f.


1.此问题与Halting Problem有关,已被证明undecidable

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,我找到了这个页面: http://lists.gnu.org/archive/html/bug-gnu-utils/2004-09/msg00098.html 亮点: GNU 链接器仍以 .o 文件粒度工作。 gcc 拉入 foo.o 然后发现 bar() 是未定义的。

    你最好把 foo_bar() 放到另一个 .o 文件中。

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 2013-08-30
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      • 2017-10-26
      相关资源
      最近更新 更多