float double
array of anything pointer to anything
The integral promotions are: char, short int and bit-field types (and signed or unsigned versions
of these), and enumeration types, will be promoted to int if they can be represented as such.
Otherwise they are promoted to unsigned int. ANSI C says that the promotion doesn't have to be
done if the compiler can guarantee that the same result occurs without it—this usually means a literal
operand.
Software Dogma
Alert! Really Important Point—Arguments Are Promoted Too!
An additional place where implicit type conversion occurs is in argument passing. Under
K&R C, since a function argument is an expression, type promotion takes place there, too.
In ANSI C, arguments are not promoted if a prototype is used; otherwise, they are. Widened
arguments are trimmed down to their declared size in the called function.
This is why the single printf() format string "%d" works for all the different types,
short, char, or int. Whichever of these you passed, an int was actually put on the
stack (or in a register, or whatever) and can be dealt with uniformly in printf [1], or any
callee at the other end. You can see this in effect if you use printf to output a type longer
than int such as long long on Sun's. Unless you use the long long format specifier
%lld, you will not get the correct value. This is because in the absence of further
information, printf assumes it is dealing with an int.
[1] Even if a prototype is in scope for printf(), note that its prototype ends with an ellipsis:
int printf(const char *format, ...);
This means it is a function that takes variable arguments. No information about the
parameters (other than the first one) is given, and the usual argument promotions always
take place.
Type conversion in C is far more widespread than in other languages, which usually restrict
themselves to making operands of different types match. C does this too, but also boosts matching
types that are smaller than the canonical forms of int or double. There are three important points to
note about implicit type conversions:
- It's a kludge in the language, dating from a desire to simplify the earliest compilers.
Converting all operands to a uniform size greatly simplified code generation. Parameters
pushed on the stack were all the same length, so the runtime system only needed to know the
number of parameters, and not their sizes. Doing all floating-point calculations at double