Home > Software engineering >  Implicit conversion in C89 and C99?
Implicit conversion in C89 and C99?

Time:10-17

I am reading the book "C programming A modern approach" K.N.King. It is written that implicit conversion happens only if

  1. if one operand has type greater that another operand. (pseudocode) long d short r

  2. rank of unsigned type of operand is the same or greater that rank of signed operand. (pseudocode) int a unsigned int b

  3. signed operand can contain any values of unsigned operand (pseudocode) long long x unsigned short y

  4. 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:

CPUs generally don't have short integer mathematical operators. `a = b * c` will compile to an integer multiplication. On x86 this is `imul`. Multiplying two 8 bit shorts will not overflow an integer, even a 16 bit integer.

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.

  • Related