Automatic Type Conversions

When a program statement mixes two different data types, QuickC performs an automatic type conversion. The following code, for instance, adds the char variable a to the int variable b.

char a = 5;

int b = 32000;

b = a + b;

In the statement

b = a + b;

the addition operation to the right of the equal sign triggers an automatic type conversion. QuickC promotes the char value to an int and then adds the two int values.

If you're not sure whether QuickC is doing an automatic type conversion, set Warning Level 2 or higher in the Customize C Compiler Options dialog box. The compiler generates the warning message

C4051: data conversion

whenever an automatic conversion occurs. This monitoring helps you readily identify unwanted conversions.

If you carelessly mix different types, you may create subtle errors. The CONVERT.C program below has a deliberate error that shows what can happen when types are mixed. It adds four variables and assigns their sum to a fifth variable, causing three promotions and one demotion.

/* CONVERT.C: Demonstrate type conversions. */

#include <stdio.h>

main()

{

char c_val = 10;

int i_val = 20;

long l_val = 64000;

float f_val = 3.1;

int result;

result = c_val + i_val + l_val + f_val; /* Error! */

printf( "%d\n", result );

}

The CONVERT.C program adds the numbers 10, 20, 64000, and 3.1. Instead of the correct result, 64033.10, the program prints

-1503

Something definitely went wrong. The problem lies somewhere in the line

result = c_val + i_val + l_val + f_val;

which triggers four automatic type conversions. We'll examine the conversions in order.

The first conversion occurs when the char variable c_val is added to the int variable i_val:

c_val + i_val

Since the variables are different types, QuickC automatically converts the lower-ranking char value to the higher-ranking int type before adding them. This promotion doesn't create any problems, since there's more than enough room to store the one-byte char value in the two-byte int. The sum of this addition is 30, another int value.

The next operation adds that partial sum to the long value of l_val (to make the expression easier to read, we'll show the sum from the previous addition):

30 + l_val

This addition triggers another promotion. The compiler promotes the int result of the first addition to a long value before adding it to l_val, which is long. Since the four-byte long type has more than enough room to store a two-byte int, this promotion is also harmless.

Now the partial sum equals 64030. The last addition from CONVERT.C

64030 + f_val

triggers another harmless conversion: the compiler converts the long result of
the previous addition to a float value before adding it to f_val. Even though
floating-point and integer values are stored in different internal formats, no
data is lost when the long is converted to a float.

The result of these additions and conversions is the float value 64033.10, which is correct. So where does the mistake occur?

The problem arises when CONVERT.C assigns the final sum to the wrong type of variable. You'll recall that the line containing these operations begins with the assignment result =.

Earlier in the program, we declared the variable result as an int. The two-byte int variable created to store the result of these additions is too small to contain the four-byte float sum that was finally produced.

The assignment forces QuickC to demote the larger float value to the smaller int type. It's impossible to store such a large floating-point value in the two bytes of an int, so the final result is incorrect.

Figure 5.2 shows the progression of automatic type conversions that the
CONVERT.C program produces.

We can fix the conversion error by declaring the variable result as a float, substituting

float result;

for the earlier declaration. We'll also need to change the format string in the printf function call to print a float value, as shown below:

printf( "%6.2f\n", result );

Now CONVERT.C prints the expected value of 64033.10.