ARM gcc settings which have been problematic for you? - Page 1
Forum section: electronics / general

author: evb149
author_rank: Regular Contributor
timestamp: May 07, 2022, 01:17:05 am
content: Hi --I'm just wondering what others' experiences have been with respect to using the GCC tool chain on ARM Cortex-M targets using C (or if you have comments on C++ that's also interesting) and encountering problems with respect to using certain options?Over the years I have encountered a few compiler bugs, and other error cases which weren't definitively problems with the compiler / libraries but also weren't clearly specific problems with the legacy MCU code base.In the latter area (legacy code errors) I think one can run into a variety of problems like absent use of 'volatile' / 'const' if it is needed, absent use of atomics / barriers / synchronization if / where that's needed, unsafe aliasing / punning, broken alignment / packing issues, timing change intolerant code, any normal sort of bug that will cause UB or memory corruption.What have been the particular issues you've encountered wrt. things like optimization, code generation, linking, etc. vs. user codeconstructs? What was able to be detected by using the toolchain's checking options etc. vs. not?

author: hans
author_rank: Super Contributor
timestamp: May 07, 2022, 07:05:10 am
content: I've one that comes to mind that screamed UB, PEBKAC but also "Why GCC, why". It was code like this:Code:uint8_t* doAllMyhomework() {uint8_t* paper;findPaper(&paper);if (paper != NULL) {doHomework(paper);submitHomework(paper);return paper;}}I would call this function, and on O0 this ran fine. It was actually by accident that it returned uint8_t* , because I thought I would need the 'allocated' paper buffer somewhere else, but in the end I did not. Anyway, when I turned up the optimizer, to my great surprise all the code was gone. I had half a library worth of calls underneath, and none was in the final disassembly. Obviously, defining a function with a pointer return type but then not returning one in any code path is not good. But the worst thing for me was all the ambiguities:- GCC 7.x and 8.x gave no warnings with default settings. Code compiled is always OK- G++ 7.x gave no warnings with default settings. Code compiled is always OK- G++ 8.x does give a warning (finally), runs fine O0, but with optimizer removes the function body code (UB)I reported this as a bug, but since this code is non-standard C++ it was not accepted. Okay, but isn't this still a bit of an user-experience thing to using your compiler? Although the compiler does give a warning, normally you wouldn't imagine that missing 1 line code would result in half your program not being generated. The difference is that in C, this code is only UB if the return result is used. In C++ it's always UB. And if the compiler needs to generate UB code , it chooses to skip it.Over the years, I see there quite a few duplicate bug reports coming in with people complaining about this discrepancy. If they just bumped up that "return missing in all control flow"-warning up to an error.. that might make the compiler as bitchy as Java, but at least you don't get these hidden surprises..Since then I switched over to -Wall and -Werror, with some turned off again (like unused variable).

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 07, 2022, 08:38:41 am
content: What makes that function to be non-standard?I'm not an expert but I see nothing wrong in it.Pointers are normally treated as volatile, so I wouldn't expect magic optimization tricks?I understand findpaper is findPaper(uint8_t ** paper).

author: hans
author_rank: Super Contributor
timestamp: May 07, 2022, 09:23:47 am
content: Not all code paths return a value.

author: evb149
author_rank: Regular Contributor
timestamp: May 07, 2022, 12:45:03 pm
content: Thanks for the good example and how the compiler has responded to it over the versions.Yes, indeed, I think a lot more scrutiny by the compiler for actually / potentially bad code is in order.It seems like every time I run a few different lint tools (with basically most serious error / warning checks enabled)I get a wide variety of different outputs from the tools and then also GCC (itself with basically all significant warnings enabled).And I think even better code checker tools still find many more cases of problems from what I've seen.So yeah "why, gcc, why..." indeed. I don't expect it to generate a good binary from bad code, but I'd sure appreciate itbeing REALLY thorough warning about bad code as least so far as it can be detected by the build / compilation / optimization process.clang tools seem to tend to do a better job with the warnings / analysis than GCC the last times I've tried them both.GCC has some nice sanitizer tools but several important cases of those don't seem to typically be supported for the MCU targets rather platforms like LINUX etc. which is a shame since if anything one can more easily have more problems on MCU code without active / full reatured MMUs, often not heavily using stable OS / libraries for many things that would be using more safe / stable code on say LINUX platforms, etc.And then you end up with all the bare metal level platform interface code that gets referenced by the user's FW but there's five thousand various non-standard types / structs / macros etc. from the MCU vendor headers / middleware but then sometimesthose files aren't easily supported by either code analysis tools or easily stubbing / mocking that stuff so one can analyze / build the main code on some other target like LINUX where at least one would get better lint and runtime checks and would stand a better chance to use clang and gcc etc. for code test / scan.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 07, 2022, 04:46:53 pm
content: I consider the '-Wall' option to be the bare minimum with GCC.Even with the latest GCC, without this option, you won't get a warning. Otherwise, the warning is: "control reaches end of non-void function [-Wreturn-type]".I also recommend the '-Wconversion' option. Forces you to be a lot more rigorous with implicit conversions, and avoid problematic ones. Of course, the "funny" part is that on third-party code, the probability of getting a ton of warnings with it is very high.Also recommend cppcheck on a regular basis. It's open-source, it's lightweight, and does a fairly decent job. cppcheck on the above code gives: "error: Found a exit path from function with non-void return type that has missing return statement ".As to bugs in GCC, I have encountered very few myself over the years. The last one I can remember was a target-specific bug on Aarch64 (64-bit ARM), and it was an alignment issue with structures with optimizations enabled. Submitted the bug back then and it got fixed in the next version.