Conversions can be either explicit or implicit. An explicit conversion is specified by a cast operator. A cast operator is a type name in parentheses preceding the expression to be converted. (You'll sometimes see the phrase "implicit cast". There's no such thing in C.)
For a given source and target type, an implicit conversion performs the same operation that a cast would perform. Some conversions, particularly most pointer conversions, are not performed implicitly and can only be done with a cast.
Implicit conversions are done in a lot of contexts in C. Some examples:
- In a simple assignment the right operand is implicitly converted to the type of the left operand. The same thing happens when passing an argument to a function, in an initializer, and when executing a
return
statement.
- When an operation like
+
is applied to operands of different arithmetic types, they are converted to a common type via a rather complicated set of rules.
- Integer types narrower than
int
are implicitly promoted to int
or to unsigned
int in many contexts.
This is not a complete list.
There are a number of implicit conversions in your example:
unsigned char a = 1;
unsigned char b = 2;
1
and 2
are of type int
. They are implicitly converted to unsigned char
by the initializer.
int c = b - a ; //presumably implicit conversion
b
and a
are both promoted to int
[but see below] before the subtraction is performed -- not because the result will be used to initialize an int
object, but because that's what the promotion rules specify. The result of the subtraction is of type int
, so the initialization doesn't need to do another conversion.
printf("%u" , (int)a - b ); // presumably casting
The cast explicitly converts a
(not a-b
) from unsigned char
to int
. b
is promoted to int
. The expression (int)a - b
is of type int
, and is passed to printf
-- which, because of the "%u"
format is expecting an argument of type unsigned int
. You can get away with mixing int
and unsigned int
in some contexts, but since the result of the subtraction is -1
, which is outside the range of unsigned int
the behavior is undefined. On my system it prints 4294967295
. With %d
, it would print -1
, which is the actual value of the expression. (You can cast to unsigned int
if you want the 4294967295
output.)
[FOOTNOTE]
I said that values of type unsigned char
are promoted to int
. In fact integer expressions of a type narrower than int
are converted to int
if int
can represent all the values of the narrow type, and to unsigned int
otherwise. On some exotic systems, it's possible that unsigned char
can represent larger values than signed int
. On such a system, unsigned char
promotes to unsigned int
. You're unlikely to encounter such a system.