c++ - G++ 不使用 -O0 编译我的源代码,但它使用 -O2 -DNDEBUG,我该如何解决?

标签 c++ compiler-construction embedded arm

我正在为 ARM 微 Controller 编写固件。我构建了没有系统调用的交叉编译器,实际上我的 RTOS (ChibiOS) 提供了一个简单的系统调用实现。

我的所有代码都是用 C 编写的,除了一些我只使用 C++ 与 Eigen 库(线性代数的 C++ 模板库,它只是标题)链接的部分。

如果我使用 -O2 -DNDEBUG 编译我的示例源代码(据我所知,使用 NDEBUG 代码将不需要 assert())一切都可以正常编译并且固件可以正常工作。

如果我使用 -O0 编译我的示例源代码,我将得到以下结果:

Linking build/ch.elf
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2    /../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-abort.o): In function `abort':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb /cortex-m4/newlib/libc/stdlib/../../../../../../../gcc-4.6.2/newlib/libc/stdlib  /abort.c:63: undefined reference to `_exit'
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-signalr.o): In function `_kill_r':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb/cortex-m4/newlib/libc/reent/../../../../../../../gcc-4.6.2/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
/home/noether/workspace/tool-chains/arm-none-eabi-4.6.2/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/cortex-m4/libc.a(lib_a-signalr.o): In function `_getpid_r':
/home/noether/workspace/tool-chains/summon-arm-toolchain/build/arm-none-eabi/thumb/cortex-m4/newlib/libc/reent/../../../../../../../gcc-4.6.2/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
collect2: ld returned 1 exit status
make: *** [build/ch.elf] Error 1

如果我输入 -DNDEBUG 也没关系,我有相同的输出。 我也在使用这些标志,-fno-exceptions 和 fno-rtti。 如果我不使用/链接 Eigen 库(唯一的 C++ 东西),即使使用 -O0,g++ 也能很好地编译源代码。

实际上,我实现了一个简单的_kill _getpid 和_exit 函数,代码编译通过了,但是代码从13KB 到130KB,然后崩溃了(可能是我没写好那些函数)。

如果我使用 -O0,我想要的是从我的代码中删除这些东西(中止等),因为它已完成(我猜)使用 -O2。

非常感谢。如果您需要更多信息,请告诉我。

最佳答案

这些引用几乎肯定是由于使用了assert();这将在失败时调用 abort(),这反过来会尝试发出信号(在此实现中使用 kill() 系统调用)以中止进程。显然,如果您不能进行系统调用,这是不可能的。

使用 -DNDEBUG 构建(就像您在优化版本中所做的那样)将解决此问题;它会导致 assert() 宏不生成任何代码,因此不会有对 abort() 的引用。优化级别本身应该没有任何区别。

或者,如果您想保留您的断言,您可以实现您自己的不需要任何系统调用的 assert() 宏。

关于c++ - G++ 不使用 -O0 编译我的源代码,但它使用 -O2 -DNDEBUG,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8832386/

相关文章:

在没有 if 语句的情况下,当计数器达到某个值时调用函数

c - 如何在Digi Module Connect me 9210中实现Modbus RTU Master

c++ - 在 C++ 中使用 "super"

c# - 当调用来自系统命名空间的函数时,c 锐利的编译器如何工作?

Scala 函数模式计算状态

java - 如何从Java程序中编译.java文件

c++ - 同一集合上的两个不同迭代器是否相等

c++ - 函数指针数组相对于 if block 的性能优势

c++ - 32 位机器上的 long long int

performance - 在单精度CPU上进行 double 计算