Multiplying char and int together in C
Question
Today I found the following:
#include <stdio.h>
int main(){
char x = 255;
int z = ((int)x)*2;
printf("%d\n", z); //prints -2
return 0;
}
So basically I'm getting an overflow because the size limit is determined by the operands on the right side of the = sign??
Why doesn't casting it to int before multiplying work?
In this case I'm using a char and int, but if I use "long" and "long long int" (c99), then I get similar behaviour. Is it generally advised against doing arithmetic with operands of different sizes?
Solution
char
can be either signed or unsigned, depending on your compiler.
In your case, it appears to be signed, and 255 is outside the range it can represent (likely, it can only represent numbers from -128 to 127).
So the problem occurs when you assign 255 to your char
variable - this results in an implementation-defined value, which in your case, appears to be -1.
When you multiply -1 by 2, you get -2. No mystery there. The cast to (int)
does nothing - types narrower than int
are always promoted to int
or unsigned int
before any calculations are done with them.
OTHER TIPS
It appears that char is signed on your platform. So the char x = 255
is effectively the same as char x = -1
. The cast to int doesn't matter.
Try changing that to:
unsigned char x = 255;
No, you are not getting an overflow on the second line (multiplication). The problem is your compiler is using signed char
by default and 255 overflows and will mean -1. Basically, you are initializing variable x
with the value of -1. Casting -1 to int will result in -1 (signed
operands will get sign-extended in upcasts whereas unsigned
operands will get zero-extended).
You can force the char
to be unsigned
by adding the unsigned
prefix:
unsigned char x = 255;
The other answers nicely explain how your example "works", so I will not explain that again.
However, let me observe that if what you want to use is an "unsigned 8 bit integer", just use <stdint.h>
's uint8_t
already (and its 16, 32, 64bit companions) and keep away from all the char
s, short
s and int
s in this world.