cancel
Showing results for 
Search instead for 
Did you mean: 

Cosmic compiler unexpected result

phorton
Associate II
Posted on February 01, 2013 at 12:05

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.
18 REPLIES 18
phorton
Associate II
Posted on February 01, 2013 at 12:19

Additionally, if I mark the test() function as ''@inline'' I get the expected result.

klaasdc
Associate II
Posted on February 01, 2013 at 13:00

Maybe ''unsigned int'' is uint8_t internally. You can check this in the types.h files.

What if you try specifying uint16_t directly?

phorton
Associate II
Posted on February 01, 2013 at 13:23

''unsigned int'' is definitely a 16-bit type, you can see it in the generated assembler output.

fggnrc2
Associate II
Posted on February 01, 2013 at 13:27

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;

EtaPhi

phorton
Associate II
Posted on February 01, 2013 at 13:42

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.

wolfgang239955_stm1_st
Associate II
Posted on February 06, 2013 at 11:09

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 codes

  return((signed int )(x-y) < 0);

 

and

  return((signed int )x - (signed int )y) < 0; 

bring absolutely identical code in the resulting .ls-file.

WoRo

fggnrc2
Associate II
Posted on February 06, 2013 at 11:24

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.

EtaPhi

wolfgang239955_stm1_st
Associate II
Posted on February 06, 2013 at 11:54

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 compiler 

MUST

DON'T NEED convert x and y into signed quantities before taking their difference.

It's quite the same result!

WoRo

fggnrc2
Associate II
Posted on February 06, 2013 at 14:47

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?