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.