[C language] Integer promotion (implicit type conversion)

         This article will introduce the implicit integer promotion in C language

1. What is integer promotion

         There is implicit type conversion in C, that is, integer arithmetic operations in C are always performed with at least the precision of the default integer type. To obtain this precision, characters and short integers in expressions must be converted to normal integers.

2. Why do you need integer promotion?

         The significance of integer promotion is that the integer operation of the expression must be executed in the corresponding computing device of the CPU. The byte length of the operand of the integer arithmetic unit (ALU) in the CPU is generally the byte length of int, and it is also the byte length of the CPU. The length of the general-purpose registers. Therefore, even if the addition of two char types is actually performed by the CPU, it must first be converted to the standard length of the integer operand in the CPU. It is difficult for a general-purpose CPU to directly add two 8-bit bytes (although there may be such byte addition instructions in machine instructions). Therefore, the various integer values ​​in the expression whose length may be smaller than the length of int must be converted to int or unsigned int before being sent to the CPU for calculation. This makes non-integer operations possible.

3. How to carry out integer improvement

The following operations are performed in the windows vs2019 x86 environment

Let's take a look at this code first:

int main()
{
	char a, b, c;
	a = 1, b = 127;
	c = a + b;
	printf("%d", c);
	return 0;
}

According to common sense, c should be 128, but the result is as follows:

This is because:

1 (decimal) =00000000 00000000 00000000 00000001 (two’s complement)

127 (decimal) = 00000000 00000000 00000000 01111111 (two's complement)

However, since a and b are signed char type numbers by default, it means a signed character type. Since the variable size of char type is one byte, that is, eight bits, and the highest bit represents the sign bit (0 is positive, 1 is negative), so the largest positive number represented is 01111111=127. So a and b will be truncated when they are assigned, and only the lowest eight bits will be assigned. so:

a=00000001

b=01111111

Integer promotion will be performed during the operation . Since the highest bits of a and b are 0, 0 is added to the high bits of a and b:

a=00000000 00000000 00000000 00000001

b=00000000 00000000 00000000 01111111

The operation result is 00000000 00000000 00000000 10000000

Since c is of char type, truncation will occur, and only the lower eight bits will be taken:

c=10000000

The highest bit of c is 1, so the integer promotion operation of c is to add 1 to the high bit of c, as follows:

c=11111111 11111111 11111111 10000000 (complement code)

Then convert to the original code:

c=10000000 00000000 00000000 10000000 (original code)

At this time, the highest bit of c is the sign bit, which is 1, which is a negative number, 10000000=128, so the result will output -128.

Integer promotion is an implicit type conversion in C language. C language also includes other type conversions. The following is another implicit type conversion:

Here is another example question:

#include <stdio.h>
int main() {
	int n = 4;
	n -= 5;
	if (n > sizeof(n))
		printf("1\n");
	if (n < sizeof(n))
		printf("2\n");
	return 0;
}

If you don’t look at it carefully, after n-=5, n should be equal to -1, and sizeof(n) should be equal to 4. It stands to reason that 1 should be output, but the result is as follows:

 Do you suddenly feel that you have found a bug in C, but in fact it is not, this is an example of how many people have been cheated by the integer promotion in C.

Now explain why you get output 1:

In this environment, int defaults to signed int (the default is different in different compilation environments)

-1=11111111 11111111 11111111 11111111 (complement code, the highest bit is the sign bit)

Since the return value of sizeof() is size_t, it is a number of type unsigned int

At this time, there is a principle in C: small to large expansion. The standard conversion rules are: short to long; signed to unsigned . Therefore, when n is compared with sizeof(n), the signed int of n will be converted into unsigned int type. At this time, the highest bit of n is no longer a sign bit but a value bit, so at this time c=4294967295, this number Will be much larger than 4 or 8. So the output is 1.

Guess you like

Origin blog.csdn.net/peng_lv/article/details/127885903