diff options
Diffstat (limited to 'devdocs/c/language%2Fconversion.html')
| -rw-r--r-- | devdocs/c/language%2Fconversion.html | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fconversion.html b/devdocs/c/language%2Fconversion.html new file mode 100644 index 00000000..f9f44d98 --- /dev/null +++ b/devdocs/c/language%2Fconversion.html @@ -0,0 +1,304 @@ + <h1 id="firstHeading" class="firstHeading">Implicit conversions</h1> <p>When an expression is used in the context where a value of a different type is expected, <i>conversion</i> may occur:</p> +<div class="c source-c"><pre data-language="c">int n = 1L; // expression 1L has type long, int is expected +n = 2.1; // expression 2.1 has type double, int is expected +char *p = malloc(10); // expression malloc(10) has type void*, char* is expected</pre></div> <p>Conversions take place in the following situations:</p> +<h3 id="Conversion_as_if_by_assignment"> Conversion as if by assignment</h3> <ul> +<li> In the <a href="operator_assignment" title="c/language/operator assignment">assignment</a> operator, the value of the right-hand operand is converted to the unqualified type of the left-hand operand. </li> +<li> In <a href="scalar_initialization" title="c/language/scalar initialization">scalar initialization</a>, the value of the initializer expression is converted to the unqualified type of the object being initialized </li> +<li> In a <a href="operator_other" title="c/language/operator other">function-call expression</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 </li> +<li> In a <a href="return" title="c/language/return">return statement</a>, the value of the operand of <code>return</code> is converted to an object having the return type of the function </li> +</ul> <p>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.</p> +<h3 id="Default_argument_promotions"> Default argument promotions</h3> <p>In a <a href="operator_other#Function_call" title="c/language/operator other">function call expression</a> when the call is made to</p> +<div class="t-li1"> +<span class="t-li">1)</span> a <a href="function_declaration" title="c/language/function declaration">function without a prototype</a> <span class="t-mark-rev t-until-c23">(until C23)</span> +</div> <div class="t-li1"> +<span class="t-li">2)</span> a <a href="variadic" title="c/language/variadic">variadic function</a>, where the argument expression is one of the trailing arguments that are matched against the ellipsis parameter</div> <p>Each argument of integer type undergoes <i>integer promotion</i> (see below), and each argument of type <code>float</code> is implicitly converted to the type <code>double</code></p> +<div class="c source-c"><pre data-language="c">int add_nums(int count, ...); +int sum = add_nums(2, 'c', true); // add_nums is called with three ints: (2, 99, 1)</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>Note that <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> and <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> are not promoted to <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> and <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> in this context.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Usual_arithmetic_conversions"> Usual arithmetic conversions</h3> <p>The arguments of the following arithmetic operators undergo implicit conversions for the purpose of obtaining the <i>common real type</i>, which is the type in which the calculation is performed:</p> +<ul> +<li> <a href="operator_arithmetic" title="c/language/operator arithmetic">binary arithmetic</a> <span class="sy2">*</span>, <span class="sy2">/</span>, <span class="sy2">%</span>, <span class="sy2">+</span>, <span class="sy2">-</span> </li> +<li> <a href="operator_comparison" title="c/language/operator comparison">relational operators</a> <span class="sy1"><</span>, <span class="sy1">></span>, <span class="sy1"><=</span>, <span class="sy1">>=</span>, <span class="sy1">==</span>, <span class="sy3">!</span><span class="sy1">=</span> </li> +<li> <a href="operator_arithmetic" title="c/language/operator arithmetic">binary bitwise arithmetic</a> <span class="sy3">&</span>, <span class="sy3">^</span>, <span class="sy3">|</span>, </li> +<li> the <a href="operator_other" title="c/language/operator other">conditional operator</a> <span class="sy4">?:</span> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <span class="t-li">1)</span> If one operand has decimal floating type, the other operand shall not have standard floating, <p>complex, or imaginary type.</p> +<ul> +<li>First, if the type of either operand is _Decimal128, the other operand is converted to _Decimal128. </li> +<li>Otherwise, if the type of either operand is _Decimal64, the other operand is converted to _Decimal64. </li> +<li>Otherwise, if the type of either operand is _Decimal32, the other operand is converted to _Decimal32.</li> +</ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <div class="t-li1"> +<span class="t-li">2)</span> Otherwise, if one operand is <code>long double</code><span class="t-rev-inl t-since-c99"><span>, <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, or <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>, the other operand is implicitly converted as follows: <ul><li>integer or real floating type to <code>long double</code> </li></ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul> +<li>complex type to <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> </li> +<li>imaginary type to <code><span class="kw4">long</span> <span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </li> +</ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> +</div> <div class="t-li1"> +<span class="t-li">3)</span> Otherwise, if one operand is <code>double</code><span class="t-rev-inl t-since-c99"><span>, <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, or <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>, the other operand is implicitly converted as follows: <ul><li>integer or real floating type to <code>double</code> </li></ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul> +<li>complex type to <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> </li> +<li>imaginary type to <code><span class="kw4">double</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </li> +</ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> +</div> <div class="t-li1"> +<span class="t-li">4)</span> Otherwise, if one operand is <code>float</code><span class="t-rev-inl t-since-c99"><span>, <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code>, or <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>, the other operand is implicitly converted as follows: <ul><li>integer type to <code>float</code> (the only real type possible is float, which remains as-is) </li></ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul> +<li>complex type remains <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/complex"><span class="kw743">complex</span></a></code> </li> +<li>imaginary type remains <code><span class="kw4">float</span> <a href="http://en.cppreference.com/w/c/numeric/complex/imaginary"><span class="kw745">imaginary</span></a></code> </li> +</ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> +</div> <div class="t-li1"> +<span class="t-li">5)</span> Otherwise, both operands are integers. Both operands undergo <i>integer promotions</i> (see below); then, after integer promotion, one of the following cases applies: <ul> +<li> If the types are the same, that type is the common type. </li> +<li> Else, the types are different: <ul> +<li> If the types have the same signedness (both signed or both unsigned), the operand whose type has the lesser <i>conversion rank</i><sup>1</sup> is implicitly converted<sup>2</sup> to the other type. </li> +<li> Else, the operands have different signedness: <ul> +<li> If the unsigned type has <i>conversion rank</i> 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. </li> +<li> Else, the unsigned type has <i>conversion rank</i> less than the signed type: <ul> +<li> 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. </li> +<li> Else, both operands undergo implicit conversion to the unsigned type counterpart of the signed operand's type.</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</div> <hr> <dl> +<dd>1. Refer to "integer promotions" below for the rules on ranking. </dd> +<dd>2. Refer to "integer conversions" under "implicit conversion semantics" below. </dd> +</dl> <div class="c source-c"><pre data-language="c">1.f + 20000001; // int is converted to float, giving 20000000.00 + // addition and then rounding to float gives 20000000.00 + +(char)'a' + 1L; // first, char 'a', which is 97, is promoted to int + // different types: int and long + // same signedness: both signed + // different rank: long is of greater rank than int + // therefore, int 97 is converted to long 97 + // the result is 97 + 1 = 98 of type signed long + +2u - 10; // different types: unsigned int and signed int + // different signedness + // same rank + // therefore, signed int 10 is converted to unsigned int 10 + // since the arithmetic operation is performed for unsigned integers + // (see "Arithmetic operators" topic), the calculation performed is (2 - 10) + // modulo (2 raised to n), where n is the number of value bits of unsigned int + // if unsigned int is 32-bit long and there is no padding bits in its object + // representation, then the result is (-8) modulo (2 raised to 32) = 4294967288 + // of type unsigned int + +5UL - 2ULL; // different types: unsigned long and unsigned long long + // same signedness + // different rank: rank of unsigned long long is greater + // therefore, unsigned long 5 is converted to unsigned long long 5 + // since the arithmetic operation is performed for unsigned integers + // (see "Arithmetic operators" topic), + // if unsigned long long is 64-bit long, then + // the result is (5 - 2) modulo (2 raised to 64) = 3 of type + // unsigned long long + +0UL - 1LL; // different types: unsigned long and signed long long + // different signedness + // different rank: rank of signed long long is greater. + // if ULONG_MAX > LLONG_MAX, then signed long long cannot represent all + // unsigned long therefore, this is the last case: both operands are converted + // to unsigned long long unsigned long 0 is converted to unsigned long long 0 + // long long 1 is converted to unsigned long long 1 since the arithmetic + // operation is performed for unsigned integers + // (see "Arithmetic operators" topic), + // if unsigned long long is 64-bit long, then + // the calculation is (0 - 1) modulo (2 raised to 64) + // thus, the result is 18446744073709551615 (ULLONG_MAX) of type + // unsigned long long</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>The result type is determined as follows:</p> +<ul> +<li> if both operands are complex, the result type is complex </li> +<li> if both operands are imaginary, the result type is imaginary </li> +<li> if both operands are real, the result type is real </li> +<li> if the two floating-point operands have different type domains (complex vs. real, complex vs imaginary, or imaginary vs. real), the result type is complex </li> +</ul> <div class="c source-c"><pre data-language="c">double complex z = 1 + 2*I; +double f = 3.0; +z + f; // z remains as-is, f is converted to double, the result is double complex</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <p>As always, the result of a floating-point operator may have greater range and precision than is indicated by its type (see <code><a href="../types/limits/flt_eval_method" title="c/types/limits/FLT EVAL METHOD">FLT_EVAL_METHOD</a></code>).</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>Note: real and imaginary operands are not implicitly converted to complex because doing so would require extra computation, while producing undesirable results in certain cases involving infinities, NaNs and signed zeros. For example, if reals were converted to complex, 2.0×(3.0+i∞) would evaluate as (2.0+i0.0)×(3.0+i∞) ⇒ (2.0×3.0–0.0×∞) + i(2.0×∞+0.0×3.0) ⇒ NaN+i∞ rather than the correct 6.0+i∞. If imaginaries were converted to complex, i2.0×(∞+i3.0) would evaluate as (0.0+i2.0) × (∞+i3.0) ⇒ (0.0×∞ – 2.0×3.0) + i(0.0×3.0 + 2.0×∞) ⇒ NaN + i∞ instead of –6.0 + i∞.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <p>Note: regardless of usual arithmetic conversions, the calculation may always be performed in a narrower type than specified by these rules under the <a href="as_if" title="c/language/as if">as-if rule</a></p> +<h3 id="Value_transformations"> Value transformations</h3> <h4 id="Lvalue_conversion"> Lvalue conversion</h4> <p>Any <a href="value_category" title="c/language/value category">lvalue expression</a> of any non-array type, when used in any context other than</p> +<ul> +<li> as the operand of the <a href="operator_member_access" title="c/language/operator member access">address-of operator</a> (if allowed) </li> +<li> as the operand of the pre/post <a href="operator_incdec" title="c/language/operator incdec">increment and decrement operators</a>. </li> +<li> as the left-hand operand of the <a href="operator_member_access" title="c/language/operator member access">member access</a> (dot) operator. </li> +<li> as the left-hand operand of the <a href="operator_assignment" title="c/language/operator assignment">assignment and compound assignment</a> operators. </li> +<li> as the operand of <a href="sizeof" title="c/language/sizeof">sizeof</a> </li> +</ul> <p>undergoes <i>lvalue conversion</i>: the type remains the same, but loses <a href="const" title="c/language/const">const</a>/<a href="volatile" title="c/language/volatile">volatile</a>/<a href="restrict" title="c/language/restrict">restrict</a>-qualifiers and <a href="atomic" title="c/language/atomic">atomic</a> properties, if any. The value remains the same, but loses its lvalue properties (the address may no longer be taken).</p> +<p>If the lvalue has incomplete type, the behavior is undefined.</p> +<p>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.</p> +<p>This conversion models the memory load of the value of the object from its location.</p> +<div class="c source-c"><pre data-language="c">volatile int n = 1; +int x = n; // lvalue conversion on n reads the value of n +volatile int* p = &n; // no lvalue conversion: does not read the value of n</pre></div> <h4 id="Array_to_pointer_conversion"> Array to pointer conversion</h4> <p>Any <a href="value_category" title="c/language/value category">lvalue expression</a> of <a href="array" title="c/language/array">array type</a>, when used in any context other than</p> +<ul> +<li> as the operand of the <a href="operator_member_access" title="c/language/operator member access">address-of operator</a> </li> +<li> as the operand of <a href="sizeof" title="c/language/sizeof">sizeof</a> </li> +<li> as the operand of <a href="typeof" title="c/language/typeof">typeof</a> and <a href="https://en.cppreference.com/mwiki/index.php?title=c/language/typeof_unqual&action=edit&redlink=1" class="new" title="c/language/typeof unqual (page does not exist)">typeof_unqual</a> <span class="t-mark-rev t-since-c23">(since C23)</span> </li> +<li> as the string literal used for <a href="array_initialization" title="c/language/array initialization">array initialization</a> </li> +</ul> <p>undergoes a conversion to the non-lvalue pointer to its first element.</p> +<p>If the array was declared <a href="storage_duration" title="c/language/storage duration">register</a>, the behavior is undefined.</p> +<div class="c source-c"><pre data-language="c">int a[3], b[3][4]; +int* p = a; // conversion to &a[0] +int (*q)[4] = b; // conversion to &b[0]</pre></div> <h4 id="Function_to_pointer_conversion"> Function to pointer conversion</h4> <p>Any function designator expression, when used in any context other than</p> +<ul> +<li> as the operand of the <a href="operator_member_access" title="c/language/operator member access">address-of operator</a> </li> +<li> as the operand of <a href="sizeof" title="c/language/sizeof">sizeof</a> </li> +<li> as the operand of <a href="typeof" title="c/language/typeof">typeof</a> and <a href="https://en.cppreference.com/mwiki/index.php?title=c/language/typeof_unqual&action=edit&redlink=1" class="new" title="c/language/typeof unqual (page does not exist)">typeof_unqual</a> <span class="t-mark-rev t-since-c23">(since C23)</span> </li> +</ul> <p>undergoes a conversion to the non-lvalue pointer to the function designated by the expression.</p> +<div class="c source-c"><pre data-language="c">int f(int); +int (*p)(int) = f; // conversion to &f +(***p)(1); // repeated dereference to f and conversion back to &f</pre></div> <h3 id="Implicit_conversion_semantics"> Implicit conversion semantics</h3> <p>Implicit conversion, whether <i>as if by assignment</i> or a <i>usual arithmetic conversion</i>, consists of two stages:</p> +<div class="t-li1"> +<span class="t-li">1)</span> value transformation (if applicable)</div> <div class="t-li1"> +<span class="t-li">2)</span> one of the conversions listed below (if it can produce the target type)</div> <h4 id="Compatible_types"> Compatible types</h4> <p>Conversion of a value of any type to any <a href="types#Compatible_types" title="c/language/types" class="mw-redirect">compatible type</a> is always a no-op and does not change the representation.</p> +<div class="c source-c"><pre data-language="c">uint8_t (*a)[10]; // if uint8_t is a typedef to unsigned char +unsigned char (*b)[] = a; // then these pointer types are compatible</pre></div> <h4 id="Integer_promotions"> Integer promotions</h4> <p>Integer promotion is the implicit conversion of a value of any integer type with <i>rank</i> less or equal to <i>rank</i> of int or of a <a href="bit_field" title="c/language/bit field">bit-field</a> of type <span class="t-rev-inl t-until-c23"><span><code>_Bool</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, <code>int</code>, <code>signed int</code>, <code>unsigned int</code>, to the value of type <code>int</code> or <code>unsigned int</code>.</p> +<p>If <code>int</code> 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 <code>int</code>. Otherwise the value is converted to <code>unsigned int</code>.</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <p>The value from a bit-field of a bit-precise integer type is converted to the corresponding bit-precise integer type. Otherwise, bit-precise integer types are exempt from the integer promotion rules.</p> +</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <p>Integer promotions preserve the value, including the sign:</p> +<div class="c source-c"><pre data-language="c">int main(void) +{ + void f(); // old-style function declaration + // since C23, void f(...) has the same behavior wrt promotions + char x = 'a'; // integer conversion from int to char + f(x); // integer promotion from char back to int +} + +void f(x) int x; {} // the function expects int</pre></div> <p><i>rank</i> above is a property of every <a href="type" title="c/language/type">integer type</a> and is defined as follows:</p> +<div class="t-li1"> +<span class="t-li">1)</span> the ranks of all signed integer types are different and increase with their precision: rank of <code>signed char</code> < rank of <code>short</code> < rank of <code>int</code> < rank of <code>long int</code> < rank of <code>long long int</code> +</div> <div class="t-li1"> +<span class="t-li">2)</span> the ranks of all signed integer types equal the ranks of the corresponding unsigned integer types</div> <div class="t-li1"> +<span class="t-li">3)</span> the rank of any standard integer type is greater than the rank of any extended integer type <span class="t-rev-inl t-since-c23"><span>or bit-precise integer type</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> of the same size (that is, rank of <code>__int64</code> < rank of <code>long long int</code>, but rank of <code>long long</code> < rank of <code>__int128</code> due to the rule <span class="t-v">(1)</span>)</div> <div class="t-li1"> +<span class="t-li">4)</span> rank of <code>char</code> equals rank of <code>signed char</code> and rank of <code>unsigned char</code> +</div> <div class="t-li1"> +<span class="t-li">5)</span> the rank of <span class="t-rev-inl t-until-c23"><span><code>_Bool</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> is less than the rank of any other standard integer type</div> <div class="t-li1"> +<span class="t-li">6)</span> the rank of any enumerated type equals the rank of its compatible integer type</div> <div class="t-li1"> +<span class="t-li">7)</span> ranking is transitive: if rank of T1 < rank of T2 and rank of T2 < rank of T3 then rank of T1 < rank of T3</div> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <span class="t-li">8)</span> the rank of a bit-precise signed integer type shall be greater than the rank of any standard integer type with less width or any bit-precise integer type with less width. <span class="t-li">9)</span> the rank of any bit-precise integer type relative to an extended integer type of the same width is implementation-defined. </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <div class="t-li1"> +<span class="t-li">10)</span> any aspects of relative ranking of extended integer types not covered above are implementation defined.</div> <p>Note: integer promotions are applied only</p> +<ul> +<li> as part of <i>usual arithmetic conversions</i> (see above) </li> +<li> as part of <i>default argument promotions</i> (see above) </li> +<li> to the operand of the unary arithmetic operators <code>+</code> and <code>-</code> </li> +<li> to the operand of the unary bitwise operator <code>~</code> </li> +<li> to both operands of the shift operators <code><<</code> and <code>>></code> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <h4 id="Boolean_conversion"> Boolean conversion</h4> <p>A value of any scalar type can be implicitly converted to <span class="t-rev-inl t-until-c23"><span><code>_Bool</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>. The values that <span class="t-rev-inl t-until-c23"><span>compare equal to an integer constant expression of value zero</span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span>are a zero (for arithmetic types), null (for pointer types) or have a type of <code><a href="../types/nullptr_t" title="c/types/nullptr t">nullptr_t</a></code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> are converted to <span class="t-rev-inl t-until-c23"><span><code>0</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>false</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, all other values are converted to <span class="t-rev-inl t-until-c23"><span><code>1</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>true</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>.</p> +<div class="c source-c"><pre data-language="c">bool b1 = 0.5; // b1 == 1 (0.5 converted to int would be zero) +bool b2 = 2.0*_Imaginary_I; // b2 == 1 (but converted to int would be zero) +bool b3 = 0.0 + 3.0*I; // b3 == 1 (but converted to int would be zero) +bool b4 = 0.0/0.0; // b4 == 1 (NaN does not compare equal to zero) +bool b5 = nullptr; // b5 == 0 (since C23: nullptr is converted to false)</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h4 id="Integer_conversions"> Integer conversions</h4> <p>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:</p> +<ul> +<li> if the target type can represent the value, the value is unchanged </li> +<li> otherwise, if the target type is unsigned, the value 2<sup class="t-su">b</sup>, 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. </li> +<li> otherwise, if the target type is signed, the behavior is implementation-defined (which may include raising a signal) </li> +</ul> <div class="c source-c"><pre data-language="c">char x = 'a'; // int -> char, result unchanged +unsigned char n = -123456; // target is unsigned, result is 192 (that is, -123456+483*256) +signed char m = 123456; // target is signed, result is implementation-defined +assert(sizeof(int) > -1); // assert fails: + // operator > requests conversion of -1 to size_t, + // target is unsigned, result is SIZE_MAX</pre></div> <h4 id="Real_floating-integer_conversions"> Real floating-integer conversions</h4> <p>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:</p> +<ul> +<li> The fractional part is discarded (truncated towards zero). </li> +<ul> +<li> If the resulting value can be represented by the target type, that value is used </li> +<li> otherwise, the behavior is undefined </li> +</ul> +</ul> <div class="c source-c"><pre data-language="c">int n = 3.14; // n == 3 +int x = 1e10; // undefined behavior for 32-bit int</pre></div> <p>A value of any integer type can be implicitly converted to any real floating type.</p> +<ul> +<li> if the value can be represented exactly by the target type, it is unchanged </li> +<li> 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 <code><a href="../numeric/fenv/fe_exceptions" title="c/numeric/fenv/FE exceptions">FE_INEXACT</a></code> is raised in this case. </li> +<li> if the value cannot be represented, the behavior is undefined, although if IEEE arithmetic is supported, <code><a href="../numeric/fenv/fe_exceptions" title="c/numeric/fenv/FE exceptions">FE_INVALID</a></code> is raised and the result value is unspecified. </li> +</ul> <p>The result of this conversion may have greater range and precision than its target type indicates (see <code><a href="../types/limits/flt_eval_method" title="c/types/limits/FLT EVAL METHOD">FLT_EVAL_METHOD</a></code>).</p> +<p>If control over <code><a href="../numeric/fenv/fe_exceptions" title="c/numeric/fenv/FE exceptions">FE_INEXACT</a></code> is needed in floating-to-integer conversions, <code><a href="../numeric/math/rint" title="c/numeric/math/rint">rint</a></code> and <code><a href="../numeric/math/nearbyint" title="c/numeric/math/nearbyint">nearbyint</a></code> may be used.</p> +<div class="c source-c"><pre data-language="c">double d = 10; // d = 10.00 +float f = 20000001; // f = 20000000.00 (FE_INEXACT) +float x = 1+(long long)FLT_MAX; // undefined behavior</pre></div> <h4 id="Real_floating_point_conversions"> Real floating point conversions</h4> <p>A value of any real floating type can be implicitly converted to any other real floating type.</p> +<ul> +<li> If the value can be represented by the target type exactly, it is unchanged </li> +<li> 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 </li> +<li> if the value cannot be represented, the behavior is undefined </li> +</ul> <p>The result of this conversion may have greater range and precision than its target type indicates (see <code><a href="../types/limits/flt_eval_method" title="c/types/limits/FLT EVAL METHOD">FLT_EVAL_METHOD</a></code>).</p> +<div class="c source-c"><pre data-language="c">double d = 0.1; // d = 0.1000000000000000055511151231257827021181583404541015625 +float f = d; // f = 0.100000001490116119384765625 +float x = 2*(double)FLT_MAX; // undefined</pre></div> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <h4 id="Complex_type_conversions"> Complex type conversions</h4> <p>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.</p> +<div class="c source-c"><pre data-language="c">double complex d = 0.1 + 0.1*I; +float complex f = d; // f is (0.100000001490116119384765625, 0.100000001490116119384765625)</pre></div> <h4 id="Imaginary_type_conversions"> Imaginary type conversions</h4> <p>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.</p> +<div class="c source-c"><pre data-language="c">double imaginary d = 0.1*_Imaginary_I; +float imaginary f = d; // f is 0.100000001490116119384765625*I</pre></div> <h4 id="Real-complex_conversions"> Real-complex conversions</h4> <p>A value of any real floating type can be implicitly converted to any complex type.</p> +<ul> +<li> The real part of the result is determined by the conversion rules for the real floating types </li> +<li> The imaginary part of the result is positive zero (or unsigned zero on non-IEEE systems) </li> +</ul> <p>A value of any complex type can be implicitly converted to any real floating type</p> +<ul> +<li> The real part is converted following the rules for the real floating types </li> +<li> The imaginary part is discarded </li> +</ul> <p>Note: in complex-to-real conversion, a NaN in the imaginary part will not propagate to the real result.</p> +<div class="c source-c"><pre data-language="c">double complex z = 0.5 + 3*I; +float f = z; // the imaginary part is discarded, f is set to 0.5 +z = f; // sets z to 0.5 + 0*I</pre></div> <h4 id="Real-imaginary_conversions"> Real-imaginary conversions</h4> <p>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 <span class="t-rev-inl t-until-c23"><span><code>_Bool</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span>, in which case boolean conversion rules apply.</p> +<p>A value of any real type can be implicitly converted to any imaginary type. The result is always a positive imaginary zero.</p> +<div class="c source-c"><pre data-language="c">double imaginary z = 3*I; +bool b = z; // Boolean conversion: sets b to true +float f = z; // Real-imaginary conversion: sets f to 0.0 +z = 3.14; // Imaginary-real conversion: sets z to 0*_Imaginary_I</pre></div> <h4 id="Complex-imaginary_conversions"> Complex-imaginary conversions</h4> <p>A value of any imaginary type can be implicitly converted to any complex type.</p> +<ul> +<li> The real part of the result is the positive zero </li> +<li> The imaginary part of the result follows the conversion rules for the corresponding real types </li> +</ul> <p>A value of any complex type can be implicitly converted to any imaginary type</p> +<ul> +<li> The real part is discarded </li> +<li> The imaginary part of the result follows the conversion rules for the corresponding real types </li> +</ul> <div class="c source-c"><pre data-language="c">double imaginary z = I * (3*I); // the complex result -3.0+0i loses real part + // sets z to 0*_Imaginary_I</pre></div> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h4 id="Pointer_conversions"> Pointer conversions</h4> <p>A pointer to <code>void</code> can be implicitly converted to and from any pointer to object type with the following semantics:</p> +<ul> +<li> If a pointer to object is converted to a pointer to void and back, its value compares equal to the original pointer. </li> +<li> No other guarantees are offered </li> +</ul> <div class="c source-c"><pre data-language="c">int* p = malloc(10 * sizeof(int)); // malloc returns void*</pre></div> <p>A pointer to an unqualified type may be implicitly converted to the pointer to qualified version of that type (in other words, <a href="const" title="c/language/const">const</a>, <a href="volatile" title="c/language/volatile">volatile</a>, and <a href="restrict" title="c/language/restrict">restrict</a> qualifiers can be added). The original pointer and the result compare equal.</p> +<div class="c source-c"><pre data-language="c">int n; +const int* p = &n; // &n has type int*</pre></div> <p>Any integer <a href="constant_expression" title="c/language/constant expression">constant expression</a> with value <code>0</code> as well as integer pointer expression with value zero cast to the type <code>void*</code> 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 <i>null pointer constant</i> and the standard library provides one definition of this constant as the macro <code><a href="../types/null" title="c/types/NULL">NULL</a></code>.</p> +<div class="c source-c"><pre data-language="c">int* p = 0; +double* q = NULL;</pre></div> <h3 id="Notes"> Notes</h3> <p>Although signed integer overflow in any arithmetic operator is undefined behavior, overflowing a signed integer type in an integer conversion is merely unspecified behavior.</p> +<p>On the other hand, although unsigned integer overflow in any arithmetic operator (and in integer conversion) is a well-defined operation and follows the rules of modulo arithmetic, overflowing an unsigned integer in a floating-to-integer conversion is undefined behavior: the values of real floating type that can be converted to unsigned integer are the values from the open interval (-1; Unnn_MAX+1).</p> +<div class="c source-c"><pre data-language="c">unsigned int n = -1.0; // undefined behavior</pre></div> <p>Conversions between pointers and integers (except <span class="t-rev-inl t-since-c99"><span>from pointer to <span class="t-rev-inl t-until-c23"><span><code>_Bool</code></span><span><span class="t-mark-rev t-until-c23">(until C23)</span></span></span><span class="t-rev-inl t-since-c23"><span><code>bool</code></span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> and </span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span>from integer constant expression with the value zero to pointer), between pointers to objects (except where either to or from is a pointer to void) and conversions between pointers to functions (except when the functions have compatible types) are never implicit and require a <a href="cast" title="c/language/cast">cast operator</a>.</p> +<p>There are no conversions (implicit or explicit) between pointers to functions and pointers to objects (including void*) or integers.</p> +<h3 id="References"> References</h3> <ul> +<li> C23 standard (ISO/IEC 9899:2023): </li> +<ul><li> 6.3 Conversions (p: TBD) </li></ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.3 Conversions (p: 37-41) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.3 Conversions (p: 50-56) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.3 Conversions (p: 42-48) </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 3.2 Conversions </li></ul> +</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/implicit_cast" title="cpp/language/implicit cast" class="mw-redirect">C++ documentation</a></span> for <span class=""><span>Implicit conversions</span></span> </td> +</tr> </table> <div class="_attribution"> + <p class="_attribution-p"> + © cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br> + <a href="https://en.cppreference.com/w/c/language/conversion" class="_attribution-link">https://en.cppreference.com/w/c/language/conversion</a> + </p> +</div> |
