2013-02-01 03:05 AM
Hi.
I'm using the Cosmic STM8 compiler (''free'' version, v4.3.9) and it appears to generate unexpected results for the following test :- static char test(unsigned int x, unsigned int y) { return (int)(x - y) < 0; } This function unexpectedly returns 0 when presented with the values x=0x7f80 and y=0x8080. If I modify the function thus is then returns 1 as expected :- static char test(unsigned int x, unsigned int y) { x -= y; return (int) x < 0; } Am I misunderstanding what the result should be ? P.2013-02-01 03:19 AM
Additionally, if I mark the test() function as ''@inline'' I get the expected result.
2013-02-01 04:00 AM
Maybe ''unsigned int'' is uint8_t internally. You can check this in the types.h files.
What if you try specifying uint16_t directly?2013-02-01 04:23 AM
''unsigned int'' is definitely a 16-bit type, you can see it in the generated assembler output.
2013-02-01 04:27 AM
Hello Peter.
There is nothing wrong in the Cosmic compiler. Your unexpected results are due to the difference between what you want and what your code says. Since x and y are unsigned values, their difference is unsigned too, so it's never negative. If you cast x-y to an integer the result is always positive or zero because the cast happens after the difference is computed. To have the expected result, you'd write: return ((int)x - (int) y) < 0; EtaPhi2013-02-01 04:42 AM
This is quite a normal construct to use when working with values that can wrap (tick counts, buffer indexes etc).
The fact that the compiler generates a different result for the inline / non-inline case would indicate that there is an issue here.2013-02-06 02:09 AM
I was testing the example and - sorry EtaPhi - in my opinion Peter would be correct.
At my configuration (CXSTM8, unlimited V4.9.10 at STVD) curiously the result is as expected. With unsigned int x,y; the codesreturn((signed int )(x-y) < 0);
and return((signed int )x - (signed int )y) < 0; bring absolutely identical code in the resulting .ls-file. WoRo
2013-02-06 02:24 AM
It's nice to hear from you again, WoRo!
If the CXSTM8 compiler outputs the same code, Peter discovered a bug of Cosmic compiler because my code has no implementation ambiguity. The compiler MUST convert x and y into signed quantities before taking their difference. EtaPhi2013-02-06 02:54 AM
Hi EtaPhi - and of course all others too,
using cast operation, any (signed or unsigned) number with the MSbit = '1' to a signed number, will result in a negative sign. With e.g. 0x7F80U - 0x8080U = 0xFF00 you'll get a negative number when casting (signed int)(0xFF00) with no respect to the type of the uncasted number. The compilerMUST
DON'T NEED convert x and y into signed quantities before taking their difference. It's quite the same result! WoRo2013-02-06 05:47 AM
I apologize for my mistake that is due to my wrong assumption that an int is a 32 bit quantity.
When x = 0x7F80 and y = 0x8080, the result should be 0xFF00 i.e. -256 and test(x,y) should return TRUE. If an int is a 32 bit quantity, the value of y becomes 0xFFFF8080 after the cast, so x - y = 0x0000FF00 = 65280 is greater than zero and test(x,y) should return FALSE. Now I wonder what is the meaning of the statement: return (int)(x-y) < 0; If x and y contain a conter reading, x - y may be the elapsed time between two events. If such is the case, why is the sign tested? I thank you, WoRo, for the lesson learned! EtaPhi. PS: what is the compiler output in the ''correct'' and in the ''wrong'' case?