I am reading the book "C programming A modern approach" K.N.King. It is written that implicit conversion happens only if
if one operand has type greater that another operand.
(pseudocode) long d short r
rank of unsigned type of operand is the same or greater that rank of signed operand.
(pseudocode) int a unsigned int b
signed operand can contain any values of unsigned operand
(pseudocode) long long x unsigned short y
when we add int to float or long to float. long long to double and so on.
But then I was writing a code and write that
int a;
short b=10000 ,c= 150;
a = b * c;
printf("result of product is %d\n", a );
I got the right answer 150000. Why? I had two operands of the same type and the implicit conversion didn't have to happen. I didn't use explicit conversion. And interestingly enough, a bit latter it is written that
int j = 1000;
long i = (long) (j * j);
This code can produce wrong result on some kind of computers maybe embedded systems, because j * j
is computed first and the result is int, but int can't hold number greater that 500.000 for example and casting would be late. I understand that (lateness of the casting) but, in fact, I did the same, but I got another.
CodePudding user response:
If the book says that implicit conversions happen only under those conditions, it is wrong. In integer arithmetic operations (and some others), operands with rank less than int
or unsigned int
are converted at least to int
or unsigned int
. (The formal rules have additional finicky details.) So, in b * c
, the short
operands b
and c
are promoted to int
, and the result type is int
. The mathematical result, 1,500,000, fits in an int
in your C implementation, so there is no overflow.
CodePudding user response:
Whereas if you are multiplying integers, you do risk an overflow of the CPU's integer multiplication operator.
(And if you use optimizations, the compiler will optimize your statement to a = 1500000
.)
You can see what your code compiles to with clang -g -S -o test.s test.c
.