Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C expression evaluating differently on two different compilers

I have code that is running differently between GCC and Atmel Studio:

uint32_t tc = 107900;
int8_t   m  = 59;

tc = tc - (m*1800);

On GCC, the result in tc is 1700, as intended.

With AtmelStudio, the result in tc is 132772, which is not correct.

The problem seems to be that the m*1800 term is being computed with the limited precision of m with AtmelStudio.

My question is, which compiler is doing it correctly?

Thank you.

like image 701
NXT Avatar asked Apr 16 '14 02:04

NXT


2 Answers

It seems that on AtmelStudio, int is 16-bit, so m*1800 overflows, invoking undefined behavior. In your case, the behavior the compiler gave was probably reduction modulo 65536 into the range [-32768,32767], yielding -24872. Then tc - (m*1800) is 132772.

To avoid this you need to cast either m or 1800 to uint32_t or some other type (e.g. long) where the result won't overflow before doing the multiplication.

like image 79
R.. GitHub STOP HELPING ICE Avatar answered Oct 27 '22 11:10

R.. GitHub STOP HELPING ICE


Both are doing it correctly. The expression m * 1800 will be calculated as type int. If int is 32 bits, then it will be 106200. If int is 16 bits, which is a perfectly acceptable way to implement a C compiler, then it's -24872.

like image 45
Lee Daniel Crocker Avatar answered Oct 27 '22 11:10

Lee Daniel Crocker