Type conversion in C is the process of converting one data type to another.
1.1 Two types of Conversion
- Implicit Type Conversion. Also known as ‘automatic type conversion’. Done by the compiler on its own, without any external trigger from the user. Generally takes place when in an expression more than one data type is present. In such conditions type conversion (type promotion) takes place to avoid loss of data.
- Explicit Type Conversion. This process is also called type casting and it is user-defined. Here the user can typecast the result to make it of a particular data type.
1.2 Scenarios of type conversions
- When a value of one type is assigned to a variable of a different type or an operator converts the type of its operand or operands before performing an operation
- When a value of one type is explicitly cast to a different type
- When a value is passed as an argument to a function or when a type is returned from a function
1.3 Integral type conversion table
From | To | Method | Consequence |
---|---|---|---|
unsigned char | signed char | Preserve bit pattern; high-order bit becomes sign bit | Misinterpreted |
unsigned char | signed short int | Zero-extend | Safe |
unsigned char | signed long int | Zero-extend | Safe |
unsigned char | unsigned short int | Zero-extend | Safe |
unsigned char | unsigned long int | Zero-extend | Safe |
unsigned short int | signed char | Preserve low-order byte | Lost |
unsigned short int | signed short int | Preserve bit pattern; high-order bit becomes sign bit | Misinterpreted |
unsigned short int | signed long int | Zero-extend | Safe |
unsigned short int | unsigned char | Preserve low-order byte | Lost |
unsigned long int | signed char | Preserve low-order byte | Lost |
unsigned long int | signed short int | Preserve low-order word | Lost |
unsigned long int | signed long int | Preserve bit pattern; high-order bit becomes sign bit | Misinterpreted |
unsigned long int | unsigned char | Preserve low-order byte | Lost |
unsigned long int | unsigned short int | Preserve low-order word | Lost |
signed char | short int | Sign-extend | Safe |
signed char | long int | Sign-extend | Safe |
signed char | unsigned char | Preserve bit pattern; high-order bit no longer sign bit | Misinterpreted |
signed char | unsigned short int | Sign-extend to short; convert short to unsigned short | Lost |
signed char | unsigned long int | Sign-extend to long; convert long to unsigned long | Lost |
signed short int | char | Truncate to low-order byte | Lost |
signed short int | long int | Sign-extend | Safe |
signed short int | unsigned char | Truncate to low-order byte | Lost |
signed short int | unsigned short int | Preserve bit pattern; high-order bit no longer sign bit | Misinterpreted |
signed short int | unsigned long int | Sign extend to long; convert long to unsigned | Lost |
signed long int | char | Truncate to low order byte | Lost |
signed long int | short int | Truncate to low order bytes | Lost |
signed long int | unsigned char | Truncate to low order byte | Lost |
signed long int | unsigned short int | Truncate to low order bytes | Lost |
2. Usual Arithmetic Conversions
The arithmetic conversions summarized below are called “usual arithmetic conversions.” These steps are applied only for binary operators that expect arithmetic type. The purpose is to yield a common type which is also the type of the result. To determine which conversions actually take place, the compiler applies the following algorithm to binary operations in the expression. The steps below are not a precedence order.
- If either operand is of type
long double
, the other operand is converted to typelong double
. - If the above condition is not met and either operand is of type
double
, the other operand is converted to typedouble
. - If the above two conditions are not met and either operand is of type
float
, the other operand is converted to typefloat
. - If the above three conditions are not met (none of the operands are of floating types), then integral conversions are performed on the operands as follows:
- If either operand is of type
unsigned long
, the other operand is converted to typeunsigned long
. - If the above condition is not met and either operand is of type
long
and the other of typeunsigned int
, both operands are converted to typeunsigned long
. - If the above two conditions are not met, and either operand is of type
long
, the other operand is converted to typelong
. - If the above three conditions are not met, and either operand is of type
unsigned int
, the other operand is converted to typeunsigned int
. - If none of the above conditions are met, both operands are converted to type
int
.
- If either operand is of type
Example
float fVal;
double dVal;
int iVal;
unsigned long ulVal;
dVal = iVal * ulVal; /* iVal converted to unsigned long
* Uses step 4.
* Result of multiplication converted to double
*/
dVal = ulVal + fVal; /* ulVal converted to float
* Uses step 3.
* Result of addition converted to double
*/
References
https://learn.microsoft.com/en-us/cpp/c-language/type-conversions-c?view=msvc-170