【问题标题】:LoopFillZerobss has an undefined reference to mainLoopF​​illZerobss 对 main 有一个未定义的引用
【发布时间】:2013-08-10 20:40:59
【问题描述】:

我正在为 STM32F4 微控制器编译一个 c++ 应用程序。 我的所有代码都编译成功,但是链接步骤失败了 以下错误:

/tmp/ccGj7Wge.o: In function `LoopFillZerobss':
(.text.Reset_Handler+0x32): undefined reference to `main'
collect2: error: ld returned 1 exit status

我熟悉未定义引用主要错误的典型原因, 也就是说,尝试编译一个根本没有 main 存在的应用程序。 但是,我确实有一个 main.cpp,当然,其中还有一个 main 函数。 它编译为 main.o,并与创建的其他目标文件链接 在编译期间。

我在 STM32F407 上进行交叉编译,并且正在运行裸机。

任何人对此有任何见解或以前见过此错误?我唯一看到 LoopF​​illZerobss 的地方 函数在板的汇编启动文件中。

【问题讨论】:

  • 那么,您的代码中没有mainLoopFillZerobss 可能是main 之前的初始化代码的一部分——用零填充块存储部分是 C 和 C++ 中初始化的一部分,因为全局变量需要设置为零。

标签: c++ linker main bare-metal stm32f4discovery


【解决方案1】:

检查事项:

  • 确保正确声明main。例如,int main(void)int main(int argc, char **argv),而不是 void main(void)。这篇 Stack Overflow 文章做得很好:What is the proper declaration of main?
  • 确保您没有不小心将main 包裹在namespace 中。
  • 如果您有一个非常古怪的 C++ 编译器,您可能需要将 main 标记为 extern "C",但老实说,我从未见过需要这样做的工具。李>

您应该能够通过在其上运行诸如nm 之类的工具来查看您的main.o 定义了哪些符号。 (至少,UNIX 风格的工具链,例如 GNU 工具链,提供了一个nm 工具。)nm 将列出您的可执行文件定义的符号集。您应该会看到 main 按原样列出。

例如,在我的 Linux 机器上,int main(void) { } 在原本为空的 .cpp 文件中会导致 nm 的以下输出:

$ nm main.o
                 U __gxx_personality_v0
0000000000000000 T main

如果我将 main 包装在命名空间中(在本例中为 namespace fred),我会得到一个像这样的错位名称:

$ nm main.o
0000000000000000 T _ZN4fred4mainEv
                 U __gxx_personality_v0

请注意名称 main 周围的额外 gobbledegook。你不应该在你的 nm 输出中看到这样的 gobbledegook。

您应该能够查看您是否正确声明了main,并且不会意外地将其放入命名空间中。一旦你得到了排序,那么初始化例程LoopFillZerobss 应该会更快乐。

【讨论】:

  • 谢谢!我的 main 包裹在一个命名空间中,现在一切正常!
猜你喜欢
  • 1970-01-01
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多