On Fri, Dec 15, 2017 at 11:40:38AM +0100, W.C.A. Wijngaards wrote: > Yes it is the compiler. Clang fails, gcc succeeds. I can make clang > succeed with a small code change together with the removal of -O2 > (disabling clang's optimizer). > > The code change is instead of if(incep - expi > 0) ..fail.. it now has > var=incep-expi; if(var > 0) ..fail..
The original coded uses non-portable undefined overflow behaviour for signed integer arithmetic. The compiler is free to replace "incep - expi > 0" with "incep > expi". The intermediate "var" may in some cases avoid the problem, but this is still brittle under optimization. To avoid non-deterministic behaviour unsigned arithmetic must be used: uint32_t incep; uint32_t expi; /* * In serial number arithmetic a > b iff as unsigned integers mod 2^32 * we have (a - b) < (b - a) */ if ((incep - expi) < (expi - incep)) { ... fail ... } The same code should be used for SOA comparisons. -- Viktor.