c/language/conversion

When an expression is used in the context where a value of a different type is expected, conversion may occur:

Conversions take place in the following situations:

Conversion as if by assignment

 * In the operator, the value of the right-hand operand is converted to the unqualified type of the left-hand operand.
 * In, the value of the initializer expression is converted to the unqualified type of the object being initialized
 * In a, to a function that has a prototype, the value of each argument expression is converted to the type of the unqualified declared types of the corresponding parameter
 * In a, the value of the operand of is converted to an object having the return type of the function

Note that actual assignment, in addition to the conversion, also removes extra range and precision from floating-point types and prohibits overlaps; those characteristics do not apply to conversion as if by assignment.

Default argument promotions
In a when the call is made to @1@ a @2@ a, where the argument expression is one of the trailing arguments that are matched against the ellipsis parameter

Each argument of integer type undergoes integer promotion (see below), and each argument of type is implicitly converted to the type

Usual arithmetic conversions
The arguments of the following arithmetic operators undergo implicit conversions for the purpose of obtaining the common real type, which is the type in which the calculation is performed:
 * the
 * the
 * the
 * the

@1@ If one operand is, the other operand is implicitly converted as follows:
 * integer or real floating type to

@2@ Otherwise, if one operand is, the other operand is implicitly converted as follows:
 * integer or real floating type to

@3@ Otherwise, if one operand is, the other operand is implicitly converted as follows:
 * integer type to (the only real type possible is float, which remains as-is)

@4@ Otherwise, both operands are integers. Both operands undergo integer promotions (see below); then, after integer promotion, one of the following cases applies:
 * If the types are the same, that type is the common type.
 * Else, the types are different:
 * If the types have the same signedness (both signed or both unsigned), the operand whose type has the lesser conversion rank1 is implicitly converted2 to the other type.
 * Else, the operands have different signedness:
 * If the unsigned type has conversion rank greater than or equal to the rank of the signed type, then the operand with the signed type is implicitly converted to the unsigned type.
 * Else, the unsigned type has conversion rank less than the signed type:
 * If the signed type can represent all values of the unsigned type, then the operand with the unsigned type is implicitly converted to the signed type.
 * Else, both operands undergo implicit conversion to the unsigned type counterpart of the signed operand's type.


 * 1. Refer to "integer promotions" below for the rules on ranking.
 * 2. Refer to "integer conversions" under "implicit conversion semantics" below.

As always, the result of a floating-point operator may have greater range and precision than is indicated by its type (see flt_eval_method).

Note: regardless of usual arithmetic conversions, the calculation may always be performed in a narrower type than specified by these rules under the

Lvalue conversion
Any of any non-array type, when used in any context other than
 * as the operand of the (if allowed)
 * as the operand of the pre/post.
 * as the left-hand operand of the (dot) operator.
 * as the left-hand operand of the operators.
 * as the operand of

undergoes lvalue conversion: the type remains the same, but loses //-qualifiers and properties, if any. The value remains the same, but loses its lvalue properties (the address may no longer be taken).

If the lvalue has incomplete type, the behavior is undefined.

If the lvalue designates an object of automatic storage duration whose address was never taken and if that object was uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

This conversion models the memory load of the value of the object from its location.

Array to pointer conversion
Any of, when used in any context other than
 * as the operand of the
 * as the operand of
 * as the string literal used for

undergoes a conversion to the non-lvalue pointer to its first element.

If the array was declared, the behavior is undefined.

Function to pointer conversion
Any function designator expression, when used in any context other than
 * as the operand of the
 * as the operand of

undergoes a conversion to the non-lvalue pointer to the function designated by the expression.

Implicit conversion semantics
Implicit conversion, whether as if by assignment or a usual arithmetic conversion, consists of two stages: @1@ value transformation (if applicable) @2@ one of the conversions listed below (if it can produce the target type)

Compatible types
Conversion of a value of any type to any is always a no-op and does not change the representation.

Integer promotions
Integer promotion is the implicit conversion of a value of any integer type with rank less or equal to rank of int or of a of type _bool,, , , to the value of type  or.

If can represent the entire range of values of the original type (or the range of values of the original bit-field), the value is converted to type. Otherwise the value is converted to.

Integer promotions preserve the value, including the sign:

rank above is a property of every and is defined as follows: @1@ the ranks of all signed integer types are different and increase with their precision: rank of < rank of  < rank of  < rank of  < rank of @2@ the ranks of all signed integer types equal the ranks of the corresponding unsigned integer types @3@ the rank of any standard integer type is greater than the rank of any extended integer type of the same size (that is, rank of < rank of, but rank of  < rank of  due to the rule ) @4@ rank of equals rank of  and rank of @5@ the rank of _bool is less than the rank of any other standard integer type @6@ the rank of any enumerated type equals the rank of its compatible integer type @7@ ranking is transitive: if rank of T1 < rank of T2 and rank of T2 < rank of T3 then rank of T1 < rank of T3 @8@ any aspects of relative ranking of extended integer types not covered above are implementation defined.

Note: integer promotions are applied only
 * as part of usual arithmetic conversions (see above)
 * as part of default argument promotions (see above)
 * to the operand of the unary arithmetic operators and
 * to the operand of the unary bitwise operator
 * to both operands of the shift operators and

{{rrev|since=c99|

Boolean conversion
A value of any scalar type can be implicitly converted to. The values that compare equal to an integer constant expression of value zero are converted to, all other values are converted to.

}}

Integer conversions
A value of any integer type can be implicitly converted to any other integer type. Except where covered by promotions and boolean conversions above, the rules are:


 * if the target type can represent the value, the value is unchanged
 * otherwise, if the target type is unsigned, the value $2b$, where $b$ is the number of value bits in the target type, is repeatedly subtracted or added to the source value until the result fits in the target type. In other words, unsigned integers implement modulo arithmetic.
 * otherwise, if the target type is signed, the behavior is implementation-defined (which may include raising a signal)

Real floating-integer conversions
A finite value of any real floating type can be implicitly converted to any integer type. Except where covered by boolean conversion above, the rules are:
 * The fractional part is discarded (truncated towards zero).
 * If the resulting value can be represented by the target type, that value is used
 * otherwise, the behavior is undefined

A value of any integer type can be implicitly converted to any real floating type.
 * if the value can be represented exactly by the target type, it is unchanged
 * if the value can be represented, but cannot be represented exactly, the result is an implementation-defined choice of either the nearest higher or nearest lower value, although if IEEE arithmetic is supported, rounding is to nearest. It is unspecified whether fe_inexact is raised in this case.
 * if the value cannot be represented, the behavior is undefined, although if IEEE arithmetic is supported, fe_invalid is raised and the result value is unspecified.

The result of this conversion may have greater range and precision than its target type indicates (see flt_eval_method).

If control over fe_inexact is needed in floating-to-integer conversions, rint and nearbyint may be used.

Real floating point conversions
A value of any real floating type can be implicitly converted to any other real floating type.
 * If the value can be represented by the target type exactly, it is unchanged
 * if the value can be represented, but cannot be represented exactly, the result is the nearest higher or the nearest lower value (in other words, rounding direction is implementation-defined), although if IEEE arithmetic is supported, rounding is to nearest
 * if the value cannot be represented, the behavior is undefined

The result of this conversion may have greater range and precision than its target type indicates (see flt_eval_method).

{{rrev|since=c99|

Complex type conversions
A value of any complex type can be implicitly converted to any other complex type. The real part and the imaginary part individually follow the conversion rules for the real floating types.

Imaginary type conversions
A value of any imaginary type can be implicitly converted to any other imaginary type. The imaginary part follows the conversion rules for the real floating types.

Real-complex conversions
A value of any real floating type can be implicitly converted to any complex type.
 * The real part of the result is determined by the conversion rules for the real floating types
 * The imaginary part of the result is positive zero (or unsigned zero on non-IEEE systems)

A value of any complex type can be implicitly converted to any real floating type
 * The real part is converted following the rules for the real floating types
 * The imaginary part is discarded

Note: in complex-to-real conversion, a NaN in the imaginary part will not propagate to the real result.

Real-imaginary conversions
A value of any imaginary type can be implicitly converted to any real type (integer or floating-point). The result is always a positive (or unsigned) zero, except when the target type is _Bool, in which case boolean conversion rules apply.

A value of any real type can be implicitly converted to any imaginary type. The result is always a positive imaginary zero.

Complex-imaginary conversions
A value of any imaginary type can be implicitly converted to any complex type.
 * The real part of the result is the positive zero
 * The imaginary part of the result follows the conversion rules for the corresponding real types

A value of any complex type can be implicitly converted to any imaginary type
 * The real part is discarded
 * The imaginary part of the result follows the conversion rules for the corresponding real types

}}

Pointer conversions
A pointer to can be implicitly converted to and from any pointer to object type with the following semantics:
 * If a pointer to object is converted to a pointer to void and back, its value compares equal to the original pointer.
 * No other guarantees are offered

A pointer to an unqualified type may be implicitly converted to the pointer to qualified version of that type (in other words,, , and qualifiers can be added). The original pointer and the result compare equal.

Any integer with value  as well as integer pointer expression with value zero cast to the type  can be implicitly converted to any pointer type (both pointer to object and pointer to function). The result is the null pointer value of its type, guaranteed to compare unequal to any non-null pointer value of that type. This integer or void* expression is known as null pointer constant and the standard library provides one definition of this constant as the macro null.