Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualBrother Bob

Posted 09 October 2012 - 02:38 PM

Thank you for explaining the situation, this clears up my doubts. I am programming an application in AVR Studio 5.1 using gcc for an Atmega328p microcontroller. Due to limited RAM on a microcontroller (2 KB) I tend to stick to 8-bit and 16-bit variables. I did some tests and it seems that increasing at least one of the vars in the equation will produce the correct result.

This does not seem to work though.
int16_t result = (uint32_t)a * b / c; // does not work

I'll do some more tests.

Regards,
Bismuth

Your variable a holds a negative value and you're casting it to an unsigned integer. Unsigned variables cannot hold negative values. And yes, it is technically enough to cast just a or b, because the other operands will be promoted automatically.


On a side note, C++ does enforce integer promotion in this situation, so the result in C++ will be as you expected.
And on yet another side note, even when I tried to reproduce your results with VS2010 compiling the code as C code, I still get -104 so it appears it does integer promotion like C++ requires even in C.

Actually, C has integer promotion rules as well (I'm pretty sure C++ got them from C in the first place). The only way that the result he's getting makes sense is if int on his compiler is 16-bits in which case manually casting to plain int isn't going to help either.

I was reading through both the C and C++ specification (the drafts only, but I doubt these details change) and the two were different in that C++ explicitly mentioned integer promotion for narrow integers and C did not; otherwise the wording was more or less identical. I did not read much more than that into it, so you may very well be right.

#1Brother Bob

Posted 09 October 2012 - 02:36 PM

Thank you for explaining the situation, this clears up my doubts. I am programming an application in AVR Studio 5.1 using gcc for an Atmega328p microcontroller. Due to limited RAM on a microcontroller (2 KB) I tend to stick to 8-bit and 16-bit variables. I did some tests and it seems that increasing at least one of the vars in the equation will produce the correct result.

This does not seem to work though.
int16_t result = (uint32_t)a * b / c; // does not work

I'll do some more tests.

Regards,
Bismuth

Your variable a holds a negative value and you're casting it to an unsigned integer. Unsigned variables cannot hold negative values. And yes, it is technically enough to cast just a or b, because the other operands will be promoted automatically.


On a side note, C++ does enforce integer promotion in this situation, so the result in C++ will be as you expected.
And on yet another side note, even when I tried to reproduce your results with VS2010 compiling the code as C code, I still get -104 so it appears it does integer promotion like C++ requires even in C.

Actually, C has integer promotion rules as well (I'm pretty sure C++ got them from C in the first place). The only way that the result he's getting makes sense is if int on his compiler is 16-bits in which case manually casting to plain int isn't going to help either.

I was reading through both the C and C++ specification (the drafts only, but I doubt these details change) and the places where the two differed were that C++ explicitly mentioned integer promotion for narrow integers and C did not; otherwise the wording was more or less identical. I did not read much more than that into it, so you may very well be right.

PARTNERS