1

I was studying the auto type conversion(auto casting) and came to the following code.

char a = 10, b = 5;
int res;
res = a / b;

I thought the auto casting happened only 2 times (char a converts to int, char b converts to int). But the answer is said to be 4 times.

Could someone please explain why the auto type conversion happens 4 times?

Learner_15
  • 399
  • 2
  • 11
  • 1
    In the initializations, `10` and `5` are both converted to `char`. In `a / b`, `a` and `b` are converted to `int`. – Tom Karzes Jul 10 '20 at 10:29

2 Answers2

3

Please note that the proper term is conversion. A conversion can either be implicit, if silently carried out by the compiler, or explicit, by means of the cast operator written by the programmer. A cast is always an explicit conversion.

There's indeed several implicit conversions taking place here. Note that integer constants like 10 are treated like int variables inside expressions.

  • a = 10 implicit conversion through assignment from int to char.
  • b = 5 implicit conversion through assignment from int to char.
  • a in a / b is integer promoted to int, as part of the usual arithemtic conversions.
  • b in a / b is integer promoted to int, as part of the usual arithemtic conversions.

The result of a / b is then of type int, same type as the = left operand res, so no further conversion in needed.

See Implicit type promotion rules for details.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • So basically, in order for the integer '10'(4byte) to settle into the character type 'a'(1 or 2byte), the integer has to convert into a character? Therefore, the two characters 'a' and 'b' are to each convert into an integer, in order for calculation? Is this right? – Learner_15 Jul 10 '20 at 11:25
  • @Learner_15 Yes that's right. Though note that character types are always 1 byte in C (although 1 byte can in theory be larger than 8 bits). – Lundin Jul 10 '20 at 12:49
-2

What really happens depeneds on the compiler implementation. What should happen is an 8 bit by 8 bit division and conversion of the result to int (16 bit or 32 bit, this depends on the target architecture and compiler).

As the CPU's usually don't have instructions for 8 bit division, the compiler may interpret this as:

res = (int)(char)((int)a / (int)b)

The char type usually should be 8 bit signed integer, in reality the compiler could optimize this to:

res = (int)a / (int)b

The "res = (int)a / (int)b" optimization is correct, if the char is treated as unsigned (this is a property of compiler). If char is signed in Your implementation, then -128 / -1 gives +128, which is not representable by signed int.

In fact char is signed in some compilers and unsigned in other compilers. It is better not to perform mathematical operations on chars. It is better to convert it to something unambiguous as soon as possible.

If You are not sure what does your compiler implementation and setup, especially in 'edge cases', then test it. If you want portable code, then avoid uncertainties. In this case it is better to use explicit typecast to avoid "edge cases". And division by zero should be avoided anyway.

Pavel S.
  • 19
  • 2
  • 1
    No, this does not depend on the compiler, the various implicit promotion rules are portable, the only thing being non-portable is the size of `int`. A compiler may optimize an expression like `a / b` to get carried out on 8 bit arithmetic, but it may only do that if it can deduct that promotion didn't cause any side effects. For example `~(unsigned char)a / (unsigned char)b` must get carried out with signed arithmetic and the left operand as a negative value - the compiler isn't allowed to optimize this into unsigned 8 bit arithmetic because that would change the meaning of the code. – Lundin Jul 10 '20 at 10:46
  • 1
    I am too long in the bussiness and seen too many things to trust You, dear Lundin. If You are not sure do not trust. Test it. Avoid uncertainties. This is the only way to reliable code in C. – Pavel S. Apr 13 '21 at 17:43
  • Sounds like a poor excuse to avoid learning how the language actually works instead of chancing and messing around with trial & error until you _think_ you got it right. Sure, C is neither rational nor easy, but all flaws of the language are very well-known by now. It's not like C++ where they introduce hundreds of new hazards every 3 years. – Lundin Apr 14 '21 at 06:39
  • I have tested this on gcc in windows: signed char cx=-128, cy=-1; int n = cx / cy; I got the result n == +128; What the compiler did is "int n = (int)cx / (int)cy;" Maybe there is some rule that the result of char operations is int in the C99? +128 is not representable in signed char. – Pavel S. Apr 16 '21 at 15:50