简体   繁体   English

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

[英]G++ does not compile my source code with -O0 but it does with -O2 -DNDEBUG, how can I solve it?

I am writing a firmware for an ARM microcontroller. 我正在为ARM微控制器编写固件。 I have built the cross-compiler without syscalls, actually my RTOS (ChibiOS) provides a simple syscalls implementation. 我建立了没有系统调用的交叉编译器,实际上我的RTOS(ChibiOS)提供了一个简单的系统调用实现。

All my code is written in C excepting some parts where I only use C++ for linking with Eigen library (a C++ template library for linear algebra, it is only headers). 我的所有代码都是用C语言编写的,除了某些部分,我仅使用C ++与Eigen库进行链接(线性代数的C ++模板库,它只是标头)。

If I compile my source example code with -O2 -DNDEBUG (as far as I know with NDEBUG the code won't need assert()) everything compiles fine and the firmware works. 如果我使用-O2 -DNDEBUG编译我的源示例代码(据我所知,使用NDEBUG,该代码将不需要assert()),那么一切都可以正常编译并且固件可以工作。

If I compile my source example code with -O0 I have the following: 如果使用-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

It does not matter if I put -DNDEBUG, I have the same output. 我放-DNDEBUG没关系,我有相同的输出。 I am using those flags as well, -fno-exceptions and fno-rtti. 我也使用了这些标志-fno-exceptions和fno-rtti。 If I do not use/link the Eigen library (the only C++ stuff), g++ compiles the source fine even with -O0. 如果我不使用/链接Eigen库(唯一的C ++东西),即使使用-O0,g ++也会很好地编译源代码。

Actually, I implemented a simple _kill _getpid and _exit functions, and the code compiles, but the code goes from 13KB to 130KB, and It crashes (maybe I haven't written well those functions). 实际上,我实现了一个简单的_kill _getpid和_exit函数,并且代码进行了编译,但是代码从13KB变为130KB,并且崩溃了(也许我没有很好地编写这些函数)。

What I want is to remove this stuff from my code (abort, etc) if I use -O0, as it is done (I guess) with -O2. 我想要的是如果我使用-O0,则从我的代码(中止等)中删除这些内容,因为使用-O2完成了(我想)。

Thank you very much. 非常感谢你。 Let me know if you need more information. 如果您需要更多信息,请与我们联系。

These references are almost certainly due to using assert() ; 这些引用几乎可以肯定是由于使用assert() that will call abort() on failure, which in turn will try to raise a signal (using the kill() syscall in this implementation) to abort the process. 它将在失败时调用abort() ,从而将尝试引发一个信号(在此实现中使用kill() syscall)以中止该进程。 Obviously, this isn't possible if you can't make syscalls. 显然,如果您无法进行系统调用,则不可能这样做。

Building with -DNDEBUG (like you do in the optimised version) will fix this; 使用-DNDEBUG (就像您在优化版本中所做的一样)将解决此问题; it causes the assert() macro to generate no code, so there will be no references to abort() . 它会使assert()宏不生成任何代码,因此将没有对abort()引用。 The optimisation level itself shouldn't make any difference. 优化级别本身不应该有任何区别。

Alternatively, if you want to preserve your assertions, you could implement your own assert() macro that doesn't require any syscalls. 另外,如果要保留断言,则可以实现自己的assert()宏,不需要任何系统调用。

You could simply implement stubs for those missing syscalls and link them to your code. 您只需为那些缺少的系统调用实现存根并将它们链接到您的代码即可。 That will keep the linker quiet, but you might make the stubs do something sensible or useful. 这样可以使链接程序保持安静,但是您可以使存根执行明智或有用的操作。 exit() might disable interrupts and loop indefinitely or force a reset. exit()可能会禁用中断并无限期循环或强制进行重置。 _kill() might hook into your RTOS to terminate a thread, or simply call _exit(), and _getpid() might return some dummy value or an RTOS thread ID. _kill()可能会挂接到您的RTOS中以终止线程,或仅调用_exit(),而_getpid()可能会返回一些虚拟值或RTOS线程ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是g ++ buggy?和clang ++呢?带有-O0和-O1选项的g ++编译代码表现不同,对于具有-O0和-O2的clang ++也是如此 - is g++ buggy ? and clang++ too ? g++ compiled code with -O0 and -O1 options behaves differently the same is true for clang++ with -O0 and -O2 模板化链接在-O2上不起作用,但在-O0上起作用 - Templated linkage does not work on -O2, but does on -O0 为什么 GCC 删除了我在 O3 上的代码,而不是在 O0 上? - Why does GCC delete my code on O3 but not on O0? 带有g ++ -O2(或-Os,-O,-O1,...)的模板警告 - Warning for template with g++ -O2 ( or -Os, -O, -O1, … ) 具有不匹配的优化级别(-O3、-O2、-O1、-O0)的二进制文件是否会导致稳定性问题? - Does having binaries with mismatched optimization levels (-O3, -O2, -O1, -O0) cause stability issues? 在premake 3.7中,如何为gcc生成-O0而不是-O2? - In premake 3.7, how do I generate -O0 instead of -O2 for gcc? g++ 优化:O2 标志修复了 O3 再次破坏的损坏代码 - g++ Optimization : O2 flag fixes a broken code where O3 breaks it again 使用-O0时,g ++在未定义的引用上停止 - g++ stops on undefined reference when using -O0 clang不编译我的代码,但g ++确实如此 - clang does not compile my code, but g++ does 如何使用g ++链接.o文件 - How can I link an .o file using g++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM