Skip to main content
MaxC
Associate II
March 3, 2024
Question

Difference between compiler optimization -O0 and -Og

  • March 3, 2024
  • 5 replies
  • 6174 views

Hello everyone,

what are the differences (regarding the debugging limitation) between the compiler options -O0 ( no optimization) and -Og ( optimized for debug) in STM32CubeIde (v 1.14.1) ?

Thanks

    5 replies

    Pavel A.
    Super User
    March 3, 2024

    -Og means optimize only as much as it does not hinder debugging (by GDB). For example, allow removal of dead code.

    AScha.3
    Super User
    March 3, 2024
    "If you feel a post has answered your question, please click ""Accept as Solution""."
    PHolt.1
    Senior
    March 3, 2024

    I don't think there is much difference when it comes to debugging.

    Well, you sometimes see "optimised away" or some such, and a variable value cannot be examined, but usually you can still see the value by looking at a register which holds it. I have very rarely used -O0 to solve this.

    Cube IDE is pretty crude and allows you to set a breakpoint on a line where there is no code. This could be a line containing C code which was stripped by the linker, or a line containing a comment :face_with_tears_of_joy: and neither breakpoint will ever get hit. Both of these cases could have been dealt with elegantly (because there are files which can be examined to see if the code exists) but nobody was bothered.

    It is just a bad system.

    The wider issue is that the "way you are supposed to work" (according to the purists) i.e. config a Debug build mode and a Release build mode, each with different optimisations etc, and debug in Debug and then use Release for the production product, is dangerous because a higher optimisation level can break code. For example when talking to a device needing specific minimum /CS timing (all of them do) it is a hassle to re-check this with a scope for every possible optimisation level. In fact sometimes one uses opt=0 for a particular function which does this kind of timing, to make sure. And 100% regression testing is impossible once you have more than about 100 lines of code. Especially over temperature, where /CS and other timing susceptibility can be large.

    So I use Debug for everything, with -Og, and never change it. And I accept that the code is not as small or not as fast as it could be. These chips are 100x fast enough for most jobs and the tiny bits of code which are truly speed critical one can optimise for speed etc for just the one function.

    Tesla DeLorean
    Guru
    March 3, 2024

    Yes, definitely tends to make things more fragile, but can also surface latent defects in the code.

    Debug what you ship, I tend to walk the optimized code, and live with it moving data to registers, and re-sequencing the code.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Pavel A.
    Super User
    March 3, 2024

    Cube IDE is pretty crude and allows you to set a breakpoint on a line where there is no code. 

    > It is just a bad system.

    Eclipse CDT editor lets you put a breakpoint at any line, but how can it know before loading the debug symbols which lines actually exist in the image. Just a little common sense, please? When the debug session starts and some breakpoints cannot be placed, the debugger should complain. If it does not, it is a defect.

     

    PHolt.1
    Senior
    March 3, 2024

    Not sure if you are saying I am right or I am s.t.u.p.i.d (this site removes that word!) :grinning_face:
    It could load the compiled data when the image gets sent to the debugger. It's all there at that time.

    Cube IDE always allowed breakpoints on comment lines :grinning_face:

    Anyway that's a side issue. The -Og or -O0 one is a good discussion. My take is that -Og is good for most stuff all the way to production. -O0 produces 30-40% more code, and mostly pointlessly; I guess one should not be getting the "optimised away" situation with variable names with -O0 but but I would use it only very temporarily.

    Another wider issue is that a change of compiler version can break timing. Think about that one :face_with_tears_of_joy: Unlikely, because most GCC changes are tiny and even more tiny if you use -Og (the new work is focused on really esoteric stuff around -O3 etc) but Cube IDE does sometimes change the compiler version. This leads to not updating Cube when working in the final stages of a project. And when archiving a project, you wrap up the whole thing, Cube and all, into a VM. I use VMWARE for this purpose.

    Andrew Neil
    Super User
    April 2, 2024

    @PHolt.1 wrote:

    Another wider issue is that a change of compiler version can break timing. 


    That's why you should never rely on HLL source code for timing - use timers, etc, instead.

     

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    PHolt.1
    Senior
    April 2, 2024

    Obviously that is the correct answer but there are cases like /CS timing where the minimum time is very short e.g. 30ns and this is easy to meet, with a large margin, by executing a few instructions. In such a case it is ok to select
    -O0 (no optimisation) for a piece of code.

    Or even use assembler.