In my embedded project, using IAR EWARM dev tools (v7.10.3), I have the following piece of code:
/* 1 */ uint32_t packet_sync = 0;
/* 2 */ uint32_t synced = 0;
/* 3 */ uint32_t gpio = 0;
/* 4 */ while (1) {
/* 5 */ if ((packet_sync != 0) && ((packet_sync = gpio) == 0)) {
/* 6 */ if (synced < 2) {
/* 7 */ synced++;
/* 8 */ }
/* 9 */ }
/* 10 */ };
From some reason, when I compile the code, the compiler gets stuck in the middle of the compilation. I tried playing around with the various constructs, and it seems like any minor change I make, removes the problem (but may make the code incorrect as well). For example, adding a NOP in #6a,and the code does compile successfully:
/* 6 */ if (synced < 2) {
/* 6a */ __NOP();
/* 7 */ synced++;
/* 8 */ }
Other examples of successful changes are removing line #7 or changing line #5 as:
/* 5 */ if ((packet_sync != 0) && ((gpio) == 0)) {
and a couple more variations.
I do not see a C rule violation in the problematic code, and it compiles just fine in Visual Studio 2013. Do I miss something? Why does this code not compile?
* Note: the code presented is an extract of the actual code and is logically meaningless.
Update: The code is compiled with the "High"/"Balanced" optimization level. With lower optimization levels, the compilation concludes just fine.
It also gets stuck when using "High" level but removing the optimization options in the "Enabled transformations:" box. Also, stuck for "Speed" and "Size" options.
Optimisation is the most complex part of any compiler and thus the most likely place for compiler bugs - especially for a "narrow market" compiler with a small development team and a smaller number if users that a desktop system compiler.
Application of optimisation has two consequences that you need to be wary of; The compiler itself may be buggy (as seems likely in this instance), and any area of "undefined behaviour" in your own code may well change behaviour under optimisation. If you need to use optimisation, you need to be prepared to test extensively - the generated code is not necessarily equivalent to the debug/development build.
In this case you should certainly report the issue to the vendor, ideally with a truly compilable example and project configuration. To solve your immediate problem judicious use of the volatile
keyword may resolve the issue - the optimiser will work hard to eliminate variables that appear to have no effect otherwise - if you can avoid the optimiser taking the same path, you may avoid the bug. If you don't use volatile
correctly, your code may well exhibit bugs in any case under optimisation. In your example, some variables certainly need to be declared volatile, but as the example is not "real" but "illustrative" it is not possible to advise.
Another possibility as a workaround is to disable optimisation selectively for this code section or source file. Do you really need optimisation to make your code work at all? If not I'd advise avoiding it in any case - not using optimisation avoids changes in behaviour between debug and released code, and makes debugging simpler in the first instance. I'd advise using optimisation as a solution to code size or performance related issues when and if they arise rather than just as a matter of course.
If the compiler literally "gets stuck", i.e. freezes up so you have to kill the process, then that's of course a compiler bug.
Figuring out why a piece of code (=the compiler) we haven't seen breaks for a particular input is very hard.
If on the other hand you mean that the compiler stops because it reports an error in your code, then of course it'd be useful to know that, and what it says.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With