Namespaces
Variants

cpp/language/implicit conversion: Difference between revisions

From cppreference.com
Fruderica (talk | contribs)
All enumeration types in C++98/03 are unscoped. No rev-box needed.
Xmcgcg (talk | contribs)
Added CWG issue #2901 DR (part 1/3).
 
(33 intermediate revisions by 11 users not shown)
Line 6: Line 6:
* when the expression is used as an operand with an operator that expects {{tt|T2}};
* when the expression is used as an operand with an operator that expects {{tt|T2}};
* when initializing a new object of type {{tt|T2}}, including {{tt|return}} statement in a function returning {{tt|T2}};
* when initializing a new object of type {{tt|T2}}, including {{tt|return}} statement in a function returning {{tt|T2}};
* when the expression is used in a {{tt|switch}} statement ({{tt|T2}} is integral type);
* when the expression is used in a {{|switch}} statement ({{tt|T2}} is integral type);
* when the expression is used in an {{tt|if}} statement or a loop ({{tt|T2}} is {{c/core|bool}}).
* when the expression is used in an {{|if}} statement or a loop ({{tt|T2}} is {{c/core|bool}}).
The program is well-formed (compiles) only if there exists one unambiguous ''implicit conversion sequence'' from {{tt|T1}} to {{tt|T2}}.  
The program is well-formed (compiles) only if there exists one unambiguous ''implicit conversion sequence'' from {{tt|T1}} to {{tt|T2}}.  


If there are multiple overloads of the function or operator being called, after the implicit conversion sequence is built from {{tt|T1}} to each available {{tt|T2}}, {{rlp|overload resolution}} rules decide which overload is compiled.
If there are multiple overloads of the function or operator being called, after the implicit conversion sequence is built from {{tt|T1}} to each available {{tt|T2}}, {{rlp|overload resolution}} rules decide which overload is compiled.


Note: in arithmetic expressions, the destination type for the implicit conversions on the operands to binary operators is determined by a separate set of rules{{rlp|operator arithmetic#Conversions|''usual arithmetic conversions''}}.
Note: in arithmetic expressions, the destination type for the implicit conversions on the operands to binary operators is determined by a separate set of rules{{rlp|usual arithmetic conversions}}.


===Order of the conversions===
===Order of the conversions===
Line 20: Line 20:
@3@ zero or one ''standard conversion sequence'' (only if a user-defined conversion is used).
@3@ zero or one ''standard conversion sequence'' (only if a user-defined conversion is used).


When considering the argument to a constructor or to a user-defined conversion function, only a standard conversion sequence is allowed (otherwise user-defined conversions could be effectively chained). When converting from one non-class type to another non-class type, only a standard conversion sequence is allowed.
When considering the argument to a constructor or to a user-defined conversion function, only standard conversion sequence is allowed (otherwise user-defined conversions could be effectively chained). When converting from one non-class type to another non-class type, only a standard conversion sequence is allowed.


A standard conversion sequence consists of the following, in this order:
A standard conversion sequence consists of the following, in this order:
@1@ zero or one conversion from the following set: ''lvalue-to-rvalue conversion'', ''array-to-pointer conversion'', and ''function-to-pointer conversion'';
@1@ zero or one conversion from the following set:
''lvalue-to-rvalue conversion'',
''array-to-pointer conversion'', and
''function-to-pointer conversion'';
@2@ zero or one ''numeric promotion'' or ''numeric conversion'';
@2@ zero or one ''numeric promotion'' or ''numeric conversion'';


Line 38: Line 41:
{{rrev|since=c++11|
{{rrev|since=c++11|
In the following contexts, the type {{c/core|bool}} is expected and the implicit conversion is performed if the declaration {{c|1=bool t(e);}} is well-formed (that is, an explicit conversion function such as {{c|explicit T::operator bool() const;}} is considered). Such expression {{c|e}} is said to be ''contextually converted to {{c/core|bool}}''.
In the following contexts, the type {{c/core|bool}} is expected and the implicit conversion is performed if the declaration {{c|1=bool t(e);}} is well-formed (that is, an explicit conversion function such as {{c|explicit T::operator bool() const;}} is considered). Such expression {{c|e}} is said to be ''contextually converted to {{c/core|bool}}''.
:* the controlling expression of {{c/core|if}}, {{c/core|while}}, {{c/core|for}};
* the controlling expression of {{c/core|if}}, {{c/core|while}}, {{c/core|for}};
:* the operands of the built-in logical operators {{tt|!}}, {{tt|&&}} and {{tt|{{!!}}}};
* the operands of the built-in logical operators {{tt|!}}, {{tt|&&}} and {{tt|{{!!}}}};
:* the first operand of the conditional operator {{tt|?:}};
* the first operand of the conditional operator {{tt|?:}};
:* the predicate in a {{rlpt|static_assert}} declaration;
* the predicate in a {{rlpt|static_assert}} declaration;
:* the expression in a {{rlpt|noexcept spec|noexcept}} specifier;
* the expression in a {{rlpt|noexcept spec|noexcept}} specifier;
{{rrev|since=c++20|
{{rrev|since=c++20|
:* the expression in an {{rlpt|explicit}} specifier;
* the expression in an {{rlpt|explicit}} specifier;
}}
}}
}}
}}
Line 58: Line 61:
Such expression {{c|e}} is said to be ''contextually implicitly converted'' to the specified type {{tt|T}}. {{rev inl|since=c++11|Note that explicit conversion functions are not considered, even though they are considered in contextual conversions to {{c/core|bool}}.}}
Such expression {{c|e}} is said to be ''contextually implicitly converted'' to the specified type {{tt|T}}. {{rev inl|since=c++11|Note that explicit conversion functions are not considered, even though they are considered in contextual conversions to {{c/core|bool}}.}}
* the argument of the {{rlp|delete|delete-expression}} ({{tt|T}} is any object pointer type);
* the argument of the {{rlp|delete|delete-expression}} ({{tt|T}} is any object pointer type);
* {{rlp|constant expression#Integral constant expression|integral constant expression}}, where a literal class is used ({{tt|T}} is any integral or unscoped enumeration type, the selected user-defined conversion function must be {{rlp|constexpr}});
* {{|constant expression#Integral constant expression}}, where a literal class is used ({{tt|T}} is any integral or unscoped enumeration type, the selected user-defined conversion function must be {{rlp|constexpr}});
* the controlling expression of the {{rlpt|switch}} statement ({{tt|T}} is any integral or enumeration type).
* the controlling expression of the {{rlpt|switch}} statement ({{tt|T}} is any integral or enumeration type).


Line 90: Line 93:


===Value transformations===
===Value transformations===
Value transformations are conversions that change the {{rlp|value category}} of an expression. They take place whenever an expression appears as an operand of an operator that expects an expression of a different value category.
Value transformations are conversions that change the {{rlp|value category}} of an expression. They take place whenever an expression appears as an operand of an operator that expects an expression of a different value category
.


====Lvalue-to-rvalue conversion====
====Lvalue-to-rvalue conversion====
{{anchor|Lvalue to rvalue conversion}}<!-- Keep the old links valid -->
{{rev inl|until=c++11|An {{|value category#lvalue}}}}{{rev inl|since=c++11|A {{|value category#glvalue}}}} of any non-function, non-array type {{tt|T}} can be implicitly converted to {{rev inl|until=c++11|an {{|value category#rvalue}}}}{{rev inl|since=c++11|a {{|value category#prvalue}}}}:
{{rev inl|until=c++11|An {{rlp|value category#lvalue|lvalue}}}}{{rev inl|since=c++11|A {{rlp|value category#glvalue|glvalue}}}} of any non-function, non-array type {{tt|T}} can be implicitly converted to {{rev inl|until=c++11|an {{rlp|value category#rvalue|rvalue}}}}{{rev inl|since=c++11|a {{rlp|value category#prvalue|prvalue}}}}:
* If {{tt|T}} is not a class type, the type of the {{rev inl|until=c++11|rvalue}}{{rev inl|since=c++11|prvalue}} is the cv-unqualified version of {{tt|T}}.
* If {{tt|T}} is not a class type, the type of the {{rev inl|until=c++11|rvalue}}{{rev inl|since=c++11|prvalue}} is the cv-unqualified version of {{tt|T}}.
* Otherwise, the type of the {{rev inl|until=c++11|rvalue}}{{rev inl|since=c++11|prvalue}} is {{tt|T}}.
* Otherwise, the type of the {{rev inl|until=c++11|rvalue}}{{rev inl|since=c++11|prvalue}} is {{tt|T}}.


If an lvalue-to-rvalue conversion from an {{rlp|type#Incomplete type|incomplete type}} is required by a program, that program is ill-formed.
If an lvalue-to-rvalue conversion from an {{|type#Incomplete type}} is required by a program, that program is ill-formed.


{{rev begin}}
{{rev begin}}
{{rev|until=c++11|
{{rev|until=c++11|
When an lvalue-to-rvalue conversion occurs within the operand of {{rlpt|sizeof}}, the value contained in the referenced object is not accessed, since that operator {{rlp|expressions#Potentially-evaluated expressions|does not evaluate}} its operand.
When an lvalue-to-rvalue conversion occurs within the operand of {{rlpt|sizeof}}, the value contained in is not accessed, since that operator {{rlp|expressions#Potentially-evaluated expressions|does not evaluate}} its operand
 
.
}}
}}
{{rev|since=c++11|
{{rev|since=c++11|
When an lvalue-to-rvalue conversion is applied to an expression {{c|E}}, the value contained in the referenced object is not accessed if:
When an lvalue-to-rvalue conversion is applied to an expression {{c|E}}, the value contained in is not accessed if:
* {{c|E}} is not {{rlp|expressions#Potentially-evaluated expressions|potentially evaluated}}, or
* {{c|E}} is not {{rlp|expressions#Potentially-evaluated expressions|potentially evaluated}}, or
* the evaluation of {{c|E}} results in the evaluation of a member {{c|Ex}} of the set of {{rlp|definition#ODR-use|potential results}} of {{c|E}}, and {{c|Ex}} names a variable {{c|x}} that is not {{rlp|definition#ODR-use|odr-used}} by {{c|Ex}}.
* the evaluation of {{c|E}} results in the evaluation of a member {{c|Ex}} of the set of {{rlp|definition#ODR-use|potential results}} of {{c|E}}, and {{c|Ex}} names a variable {{c|x}} that is not {{rlp|definition#ODR-use|odr-used}} by {{c|Ex}}.
}}
{{rev end}}
 


{{rev begin}}
{{rev begin}}
{{rev|until=c++11|
{{rev|until=c++|
The result of the conversion is the value contained in the object indicated by the lvalue.
The result of the conversion is the .
}}
}}
{{rev|since=c++11|
{{rev|since=c++17|
The result of the conversion is determined according to the following rules:
::* conversion {{rlp|copy initialization|copy-initializes}} the [[#Temporary materialization|result object]] from the glvalue.
* If {{tt|T}} is (possibly cv-qualified) {{lc|std::nullptr_t}}, the result is a {{rlp|pointer#Null pointers|null pointer constant}}. The object to which the glvalue refers is not accessed by the conversion, so there is no side effect even if {{tt|T}} is volatile-qualified, and the glvalue can refer to an inactive member of a union.
* Otherwise, if T has a class type,
{{rrev multi|until1=c++17|rev1=
:* the conversion {{rlp|copy initialization|copy-initializes}} a {{rlp|lifetime#Temporary object lifetime|temporary}} of type {{tt|T}} from the glvalue, and the result of the conversion is a prvalue for the temporary.
|rev2=
:* the conversion {{rlp|copy initialization|copy-initializes}} the [[#Temporary materialization|result object]] from the glvalue.
}}
}}
* Otherwise, if the object to which the glvalue refers contains an invalid pointer value, the behavior is implementation-defined.
* Otherwise, {{rev inl|since=c++20|the object indicated by the glvalue is read, and}} the result is the value contained in the object.
* Otherwise, if contains an invalid pointer value, the behavior is implementation-defined.
* Otherwise, {{rev inl|since=c++20|is read, and}} the result is the value contained in the .
}}
}}
{{rev end}}
{{rev end}}
Line 134: Line 140:
====Array-to-pointer conversion====
====Array-to-pointer conversion====
{{anchor|Array to pointer conversion}}<!-- Keep the old links valid -->
{{anchor|Array to pointer conversion}}<!-- Keep the old links valid -->
An {{rlp|value category#lvalue|lvalue}} or {{rlp|value category#rvalue|rvalue}} of type "array of {{tt|N}} {{tt|T}}" or "array of unknown bound of {{tt|T}}" can be implicitly converted to a {{rlp|value category#prvalue|prvalue}} of type "pointer to {{tt|T}}". {{rev inl|since=c++17|If the array is a prvalue, [[#Temporary materialization|temporary materialization]] occurs.}} The resulting pointer refers to the first element of the array (see {{rlp|array#Array-to-pointer decay|array to pointer decay}} for details)
An {{|value category#lvalue}} or {{|value category#rvalue}} of type of {{|N}} {{tt|T}}or of unknown bound of {{tt|T}}can be implicitly converted to a {{|value category#prvalue}} of type to {{tt|T}}. {{rev inl|since=c++17|If the array is a prvalue, #Temporary materializationoccurs.}} The resulting pointer refers to the first element of the array (see {{|array#Array-to-pointer decay
 
|to pointer }}


{{rrev|since=c++17|
{{rrev|since=c++17|
====Temporary materialization====
====Temporary materialization====
A {{rlp|value category#prvalue|prvalue}} of any complete type {{tt|T}} can be converted to an xvalue of the same type {{tt|T}}. This conversion initializes a {{rlp|lifetime#Temporary object lifetime|temporary object}} of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.  
A {{|value category#prvalue}} of any complete type {{tt|T}} can be converted to an xvalue of the same type {{tt|T}}. This conversion initializes a {{rlp|lifetime#Temporary object lifetime|temporary object}} of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.
If {{tt|T}} is a class or array of class type, it must have an accessible and non-deleted destructor.
If {{tt|T}} is a class or array of class type, it must have an accessible and non-deleted destructor.
{{source|1=
{{source|1=
Line 145: Line 156:
               // S() prvalue is converted to xvalue
               // S() prvalue is converted to xvalue
}}
}}
Temporary materialization occurs in the following situations:
Temporary materialization occurs in the following situations:
* when {{rlp|reference initialization|binding a reference}} to a prvalue;
* when {{rlp|reference initialization|binding a reference}} to a prvalue;
* when performing a {{rlp|operator member access|member access}} on a class prvalue;
* when a
{{rlp|operator member |member }} a class prvalue;
* when performing an array-to-pointer conversion (see above) or {{rlp|operator member access#Built-in subscript operator|subscripting}} on an array prvalue;
* when performing an array-to-pointer conversion (see above) or {{rlp|operator member access#Built-in subscript operator|subscripting}} on an array prvalue;
* when initializing an object of type {{lc|std::initializer_list<T>}} from a {{rlp|list initialization|braced-init-list}};
* when initializing an object of type {{|std::initializer_list<T>}} from a {{rlp|initialization|braced-list}};
* when {{rlpt|typeid}} is applied to a prvalue (this is part of an unevaluated expression);
* when {{rlpt|sizeof}} is applied to a prvalue (this is part of an unevaluated expression);
* when a prvalue appears as a {{rlp|expressions#Discarded-value expressions|discarded-value expression}}.
* when a prvalue appears as a {{rlp|expressions#Discarded-value expressions|discarded-value expression}}.


Note that temporary materialization does ''not'' occur when initializing an object from a prvalue of the same type (by {{rlp|direct initialization|direct-initialization}} or {{rlp|copy initialization|copy-initialization}}): such object is initialized directly from the initializer. This ensures "guaranteed copy elision".
Note that temporary materialization does ''not'' occur when initializing an object from a prvalue of the same type (by {{rlp|direct initialization|direct-initialization}} or {{rlp|copy initialization|copy-initialization}}): such object is initialized directly from the initializer. This ensures copy
 
 
.
 
 
 
}}
}}


====Function-to-pointer conversion====
========
{{anchor|Function to pointer}}<!-- Keep the old links valid -->
{{|to
An {{rlp|value category#lvalue|lvalue}} of function type {{tt|T}} can be implicitly converted to a {{rlp|value category#prvalue|prvalue}} {{rlp|pointer#Pointers to functions|pointer to that function}}. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.
}}
{{|
|}}
{{|}}
{{rlp|#|}}
{{|#|}}
.


===Numeric promotions===
====Integral promotion====
{{rlp|value category#prvalue|prvalue}}s of small integral types (such as {{c/core|char}}) may be converted to prvalues of larger integral types (such as {{c/core|int}}). In particular, {{rlp|operator arithmetic|arithmetic operators}} do not accept types smaller than {{c/core|int}} as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable. This conversion always preserves the value.


The following implicit conversions are classified as integral promotions:
{{|since=c++11|
:* {{c/core|signed char}} or {{c/core|short}} can be converted to {{c/core|int}};
an unscoped enumeration type whose underlying type is fixed can be converted to its underlying type, if the underlying type is also subject to integral promotion, to the promoted underlying type. Conversion to the unpromoted underlying type is better for the purposes of {{rlp|overload resolution}}
:* {{c/core|unsigned char}} or {{c/core|unsigned short}} can be converted to {{c/core|int}} if it can hold its entire value range, and {{c/core|unsigned int}} otherwise;
}}
:* {{c/core|char}} can be converted to {{c/core|int}} or {{c/core|unsigned int}} depending on the underlying type: {{c/core|signed char}} or {{c/core|unsigned char}} (see above);
:* {{c/core|wchar_t}}{{rev inl|since=c++20|, {{c/core|char8_t}}}}{{rev inl|since=c++11|, {{c/core|char16_t}}, and {{c/core|char32_t}}}} can be converted to the first type from the following list able to hold their entire value range: {{c/core|int}}, {{c/core|unsigned int}}, {{c/core|long}}, {{c/core|unsigned long}}{{rev inl|since=c++11|, {{c/core|long long}}, {{c/core|unsigned long long}}}};
:* an unscoped {{rlp|enum|enumeration}} type whose underlying type is not fixed can be converted to the first type from the following list able to hold their entire value range: {{c/core|int}}, {{c/core|unsigned int}}, {{c/core|long}}, {{c/core|unsigned long}}{{rev inl|since=c++11|, {{c/core|long long}}, or {{c/core|unsigned long long}}, extended integer types with higher conversion rank (in rank order, signed given preference over unsigned)}}. If the value range is greater, no integral promotions apply;
:* an unscoped enumeration type whose underlying type is fixed can be converted to its underlying type, and, if the underlying type is also subject to integral promotion, to the promoted underlying type. Conversion to the unpromoted underlying type is better for the purposes of {{rlp|overload resolution}};
:* a {{rlp|bit field|bit-field}} type can be converted to {{c/core|int}} if it can represent entire value range of the bit-field, otherwise to {{c/core|unsigned int}} if it can represent entire value range of the bit-field, otherwise no integral promotions apply;
:* the type {{c/core|bool}} can be converted to {{c/core|int}} with the value {{c|false}} becoming {{c|0}} and {{c|true}} becoming {{c|1}}.


Note that all other conversions are not promotions; for example, {{rlp|overload resolution}} chooses {{c/core|char}} -> {{c/core|int}} (promotion) over {{c/core|char}} -> {{c/core|short}} (conversion).
-
{{|}} {{c/core|}} {{c/core|}}.


====Floating-point promotion====
-point promotion.
A {{rlp|value category#prvalue|prvalue}} of type {{c/core|float}} can be converted to a prvalue of type {{c/core|double}}. The value does not change.


===Numeric conversions===
===Numeric conversions===
Line 184: Line 228:


====Integral conversions====
====Integral conversions====
A {{rlp|value category#prvalue|prvalue}} of an integer type or of an unscoped enumeration type can be converted to any other integer type. If the conversion is listed under integral promotions, it is a promotion and not a conversion.
A {{|value category#prvalue}} of an integer type or of an unscoped enumeration type can be converted to any other integer type. If the conversion is listed under integral promotions, it is a promotion and not a conversion.
:* If the destination type is unsigned, the resulting value is the smallest unsigned value equal to the source value [[enwiki:Modular arithmetic|modulo]] {{math|2{{su|p=n}}}} where {{math|n}} is the number of bits used to represent the destination type.
* If the destination type is unsigned, the resulting value is the smallest unsigned value equal to the source value enwikiModular arithmetic|modulo{{math|2{{su|p=n}}}} where {{math|n}} is the number of bits used to represent the destination type.
:: That is, depending on whether the destination type is wider or narrower, signed integers are sign-extended<ref group="footnote">This only applies if the arithmetic is two's complement which is only required for the [[cpp/types/integer|exact-width integer types]]. Note, however, that at the moment all platforms with a C++ compiler use two's complement arithmetic</ref> or truncated and unsigned integers are zero-extended or truncated respectively.
:That is, depending on whether the destination type is wider or narrower, signed integers are sign-extended<ref>This only applies if the arithmetic is two's complement which is only required for the [[cpp/types/integer|exact-width integer types]]. Note, however, that at the moment all platforms with a C++ compiler use two's complement arithmetic</ref> or truncated and unsigned integers are zero-extended or truncated respectively.
:* If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is {{rev inl|until=c++20|implementation-defined}}{{rev inl|since=c++20|the unique value of the destination type equal to the source value modulo {{math|2{{su|p=n}}}} where {{math|n}} is the number of bits used to represent the destination type.}}. (Note that this is different from {{rlp|operator arithmetic#Overflows|signed integer arithmetic overflow}}, which is undefined).
* If the destination type is signed, the value does not change if the source integer can be represented in the destination type. Otherwise the result is {{rev inl|until=c++20|implementation-defined}}{{rev inl|since=c++20|the unique value of the destination type equal to the source value modulo {{math|2{{su|p=n}}}} where {{math|n}} is the number of bits used to represent the destination type}} (that this is different from {{rlp|operator arithmetic#Overflows|signed integer arithmetic overflow}}, which is undefined).
:* If the source type is {{c/core|bool}}, the value {{c|false}} is converted to zero and the value {{c|true}} is converted to the value one of the destination type (note that if the destination type is {{c/core|int}}, this is an integer promotion, not an integer conversion).
* If the source type is {{c/core|bool}}, the value {{c|false}} is converted to zero and the value {{c|true}} is converted to the value one of the destination type (note that if the destination type is {{c/core|int}}, this is an integer promotion, not an integer conversion).
:* If the destination type is {{c/core|bool}}, this is a [[#Boolean conversions|boolean conversion]] (see below).
* If the destination type is {{c/core|bool}}, this is a [[#Boolean conversions|boolean conversion]] (see below).


====Floating-point conversions====
====Floating-point conversions====
A {{rlp|value category#prvalue|prvalue}} of a floating-point type can be converted to a prvalue of any other floating-point type. If the conversion is listed under floating-point promotions, it is a promotion and not a conversion.
:* If the source value can be represented exactly in the destination type, it does not change.
:* If the source value is between two representable values of the destination type, the result is one of those two values (it is implementation-defined which one, although if IEEE arithmetic is supported, rounding defaults [[cpp/numeric/fenv/FE_round|to nearest]]).
A {{|value category#prvalue
:* Otherwise, the behavior is undefined.
|prvalue}} of a floating-point type can be converted to a prvalue of any other floating-point type .
 
 
 
If the conversion is listed under floating-point promotions, it is a promotion and not a conversion.
* If the source value can be represented exactly in the destination type, it does not change.
* If the source value is between two representable values of the destination type, the result is one of those two values (it is implementation-defined which one, although if IEEE arithmetic is supported, rounding defaults [[cpp/numeric/fenv/FE_round|to nearest]]).
* Otherwise, the behavior is undefined.


====Floating–integral conversions====
====Floating–integral conversions====
:* A {{rlp|value category#prvalue|prvalue}} of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded. If the value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply). If the destination type is {{c/core|bool}}, this is a boolean conversion (see below).
A {{|value category#prvalue}} of floating-point type can be converted to a prvalue of any integer type. The fractional part is truncated, that is, the fractional part is discarded.
:* A prvalue of integer or unscoped enumeration type can be converted to a prvalue of any floating-point type. The result is exact if possible. If the value can fit into the destination type but cannot be represented exactly, it is implementation defined whether the closest higher or the closest lower representable value will be selected, although if IEEE arithmetic is supported, rounding defaults [[cpp/numeric/fenv/FE_round|to nearest]]. If the value cannot fit into the destination type, the behavior is undefined. If the source type is {{c/core|bool}}, the value {{c|false}} is converted to zero, and the value {{c|true}} is converted to one.
If the value cannot fit into the destination type, the behavior is undefined (even when the destination type is unsigned, modulo arithmetic does not apply).
If the destination type is {{c/core|bool}}, this is a boolean conversion (see below).
 
A prvalue of integer or unscoped enumeration type can be converted to a prvalue of any floating-point type. The result is exact if possible.
If the value can fit into the destination type but cannot be represented exactly, it is implementation defined whether the closest higher or the closest lower representable value will be selected, although if IEEE arithmetic is supported, rounding defaults [[cpp/numeric/fenv/FE_round|to nearest]].
If the value cannot fit into the destination type, the behavior is undefined.
If the source type is {{c/core|bool}}, the value {{c|false}} is converted to zero, and the value {{c|true}} is converted to one.


====Pointer conversions====
====Pointer conversions====
:* A ''null pointer constant'' (see {{lc|NULL}}), can be converted to any pointer type, and the result is the null pointer value of that type. Such conversion (known as ''null pointer conversion'') is allowed to convert to a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions.
A null pointer constant}} can be converted to any pointer type, and the result is the null pointer value of that type. Such conversion (known as ''null pointer conversion'') is allowed to convert to a cv-qualified type as a single conversion, that is, it not considered a combination of numeric and qualifying conversions.
:* A {{rlp|value category#prvalue|prvalue}} pointer to any (optionally cv-qualified) object type {{tt|T}} can be converted to a prvalue pointer to (identically cv-qualified) {{c/core|void}}. The resulting pointer represents the same location in memory as the original pointer value. If the original pointer is a null pointer value, the result is a null pointer value of the destination type.
 
:* A prvalue pointer to a (optionally cv-qualified) derived complete class type can be converted to a prvalue pointer to its (identically cv-qualified) base class. If the base class is inaccessible or ambiguous, the conversion is ill-formed (won't compile). The result of the conversion is a pointer to the base class subobject within the pointed-to object. The null pointer value is converted to the null pointer value of the destination type.
A {{|value category#prvalue}} pointer to any (optionally cv-qualified) object type {{tt|T}} can be converted to a prvalue pointer to (identically cv-qualified) {{c/core|void}}. The resulting pointer represents the same location in memory as the original pointer value.
If the original pointer is a null pointer value, the result is a null pointer value of the destination type.
 
A prvalue to (cv-qualified) can be converted to a prvalue to (cv-qualified) base class. If the is inaccessible or ambiguous, the is ill-formed.
result is a pointer
base classwithin the .
pointer to the of the .


====Pointer-to-member conversions====
====Pointer-to-member conversions====
:* A ''null pointer constant'' (see {{lc|NULL}}) can be converted to any pointer-to-member type, and the result is the null member pointer value of that type. Such conversion (known as ''null member pointer conversion'') is allowed to convert to a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions.
A null pointer constant}} can be converted to any pointer-to-member type, and the result is the null member pointer value of that type. Such conversion (known as ''null member pointer conversion'') is allowed to convert to a cv-qualified type as a single conversion, that is, it not considered a combination of numeric and qualifying conversions.
:* A {{rlp|value category#prvalue|prvalue}} pointer to member of some type {{tt|T}} in a base class {{tt|B}} can be converted to a {{rlp|value category#prvalue|prvalue}} pointer to member of the same type {{tt|T}} in its derived complete class {{tt|D}}. If {{tt|B}} is inaccessible, ambiguous, or virtual base of {{tt|D}} or is a base of some intermediate virtual base of {{tt|D}}, the conversion is ill-formed (won't compile). The resulting pointer can be dereferenced with a {{tt|D}} object, and it will access the member within the {{tt|B}} base subobject of that {{tt|D}} object. The null pointer value is converted to the null pointer value of the destination type.
 
A {{|value category#prvalue}} to member of {{tt|}} {{tt|}}can be converted to a {{|}} of type {{tt|T}}class {{tt|}} . If {{tt|}} is inaccessible, ambiguous, or virtual base of {{tt|}} or is a base of some intermediate virtual base of {{tt|}}, the is ill-formed.
resulting pointer can be dereferenced with a {{tt|}} object, and it will access the member within the {{tt|}} base subobject of that {{tt|}} object.


====Boolean conversions====
====Boolean conversions====
A {{rlp|value category#prvalue|prvalue}} of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type {{c/core|bool}}.
A {{|value category#prvalue}} of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type {{c/core|bool}}.


The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become {{c|false}}. All other values become {{c|true}}.
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become {{c|false}}. All other values become {{c|true}}.
Line 220: Line 293:


===Qualification conversions===
===Qualification conversions===
:* A {{rlp|value category#prvalue|prvalue}} of type pointer to {{rlp|cv|cv-qualified}} type {{tt|T}} can be converted to a prvalue pointer to a more cv-qualified same type {{tt|T}} (in other words, constness and volatility can be added).
:
:* A prvalue of type pointer to member of cv-qualified type {{tt|T}} in class {{tt|X}} can be converted to a prvalue pointer to member of more cv-qualified type {{tt|T}} in class {{tt|X}}.
* A {{|value category#prvalue}} of type pointer to {{rlp|cv|cv-qualified}} type {{tt|T}} can be converted to a prvalue pointer to a more cv-qualified same type {{tt|T}} (in other words, constness and volatility can be added).
"More" cv-qualified means that
* A prvalue of type pointer to member of cv-qualified type {{tt|T}} in class {{tt|X}} can be converted to a prvalue pointer to member of more cv-qualifiedtype {{tt|T}} in class {{tt|X}}.
:* a pointer to ''unqualified'' type can be converted to a pointer to {{c/core|const}};
 
:* a pointer to ''unqualified'' type can be converted to a pointer to {{c/core|volatile}};
cv-
:* a pointer to ''unqualified'' type can be converted to a pointer to {{c/core|const volatile}};
 
:* a pointer to {{c/core|const}} type can be converted to a pointer to {{c/core|const volatile}};
:* a pointer to {{c/core|volatile}} type can be converted to a pointer to {{c/core|const volatile}}.
''''
type
to to
 
{{c/core|const }} ;
*{{c/core|}} ;
*{{c/core|const }} ;
*{{c/core|const}} {{c/core|}} ;
*{{c/core|}} {{c/core|const }}
 
.


For multi-level pointers, the following restrictions apply: a multilevel pointer {{tt|P1}} which is {{math|cv{{su|b=0|p=1}}}}-qualified pointer to {{math|cv{{su|b=1|p=1}}}}-qualified pointer to ... {{math|cv{{su|b=n-1|p=1}}}}-qualified pointer to {{math|cv{{su|b=n|p=1}}}}-qualified {{tt|T}} is convertible to a multilevel pointer {{tt|P2}} which is {{math|cv{{su|b=0|p=2}}}}-qualified pointer to {{math|cv{{su|b=1|p=2}}}}-qualified pointer to ... {{math|cv{{su|b=n-1|p=2}}}}-qualified pointer to {{math|cv{{su|b=n|p=2}}}}-qualified {{tt|T}} only if
-a {{tt|}} is {{|{{||}} }}-
:* the number of levels {{tt|n}} is the same for both pointers;
{{|{{||}}
{{rrev|since=c++20|
}}
:* at every level that array type is involved in, at least one array type has unknown bound, or both array types have same size;
to
.
 
{{|cv{{|
 
=
n -
1
 
= 1
 
}} }} -
{{|{{|=|}} }}
 
-
 
 
 
{{tt|}} is {{tt|}}