______________________________________________________________________
4 Standard conversions [conv]
______________________________________________________________________
1 Standard conversions are implicit conversions defined for built-in
types. The full set of such conversions is enumerated in this clause.
A standard conversion sequence is a sequence of standard conversions
in the following order:
--Zero or one conversion from the following set: lvalue-to-rvalue con-
version, array-to-pointer conversion, and function-to-pointer con-
version.
--Zero or one conversion from the following set: integral promotions,
floating point promotion, integral conversions, floating point con-
versions, floating-integral conversions, pointer conversions,
pointer to member conversions, and boolean conversions.
--Zero or one qualification conversion.
[Note: a standard conversion sequence can be empty, i.e., it can con-
sist of no conversions. ] A standard conversion sequence will be
applied to an expression if necessary to convert it to a required des-
tination type.
2 [Note: expressions with a given type will be implicitly converted to
other types in several contexts:
--When used as operands of operators. The operator's requirements for
its operands dictate the destination type. See _expr_.
--When used in the condition of an if statement or iteration statement
(_stmt.select_, _stmt.iter_). The destination type is bool.
--When used in the expression of a switch statement. The destination
type is integral (_stmt.select_).
--When used as the source expression for an initialization (which
includes use as an argument in a function call and use as the
expression in a return statement). The type of the entity being
initialized is (generally) the destination type. See _dcl.init_,
_dcl.init.ref_.
--end note]
3 An expression e can be implicitly converted to a type T if and only if
the declaration T t=e;" is well-formed, for some invented temporary
variable t (_dcl.init_). The effect of the implicit conversion is the
same as performing the declaration and initialization and then using
the temporary variable as the result of the conversion. The result is
an lvalue if T is a reference type (_dcl.ref_), and an rvalue other-
wise. The expression e is used as an lvalue if and only if the ini-
tialization uses it as an lvalue.
4 [Note: For user-defined types, user-defined conversions are considered
as well; see _class.conv_. In general, an implicit conversion
sequence (_over.best.ics_) consists of a standard conversion sequence
followed by a user-defined conversion followed by another standard
conversion sequence.
5 There are some contexts where certain conversions are suppressed. For
example, the lvalue-to-rvalue conversion is not done on the operand of
the unary & operator. Specific exceptions are given in the descrip-
tions of those operators and contexts. ]
4.1 Lvalue-to-rvalue conversion [conv.lval]
1 An lvalue (_basic.lval_) of a non-function, non-array type T can be
converted to an rvalue. If T is an incomplete type, a program that
necessitates this conversion is ill-formed. If the object to which
the lvalue refers is not an object of type T and is not an object of a
type derived from T, or if the object is uninitialized, a program that
necessitates this conversion has undefined behavior. If T is a non-
class type, the type of the rvalue is the cv-unqualified version of T.
Otherwise, the type of the rvalue is T. 1)
2 The value contained in the object indicated by the lvalue is the
rvalue result. When an lvalue-to-rvalue conversion occurs within the
operand of sizeof (_expr.sizeof_) the value contained in the refer-
enced object is not accessed, since that operator does not evaluate
its operand.
3 [Note: See also _basic.lval_. ]
4.2 Array-to-pointer conversion [conv.array]
1 An lvalue of type "array of N T" or "array of unknown bound of T" can
be converted to an rvalue of type "pointer to T." The result is a
pointer to the first element of the array.
2 A string literal (_lex.string_) that is not a wide string literal can
be converted to an rvalue of type "pointer to char"; a wide string
literal can be converted to an rvalue of type "pointer to wchar_t".
In either case, the result is a pointer to the first element of the
array. [Note: this conversion is deprecated. See Annex _depr_. ]
For the purpose of ranking in overload resolution (_over.ics.scs_),
_________________________
1) In C++ class rvalues can have cv-qualified types (because they are
objects). This differs from ISO C, in which non-lvalues never have
cv-qualified types.
this conversion is considered an array-to-pointer conversion followed
by a qualification conversion (_conv.qual_). [Example: "abc" is con-
verted to "pointer to const char" as an array-to-pointer conversion,
and then to "pointer to char" as a qualification conversion. ]
4.3 Function-to-pointer conversion [conv.func]
1 An lvalue of function type T can be converted to an rvalue of type
"pointer to T." The result is a pointer to the function.2)
2 [Note: See _over.over_ for additional rules for the case where the
function is overloaded. ]
4.4 Qualification conversions [conv.qual]
1 An rvalue of type "pointer to cv1 T" can be converted to an rvalue of
type "pointer to cv2 T" if "cv2 T" is more cv-qualified than "cv1 T."
2 An rvalue of type "pointer to member of X of type cv1 T" can be con-
verted to an rvalue of type "pointer to member of X of type cv2 T" if
"cv2 T" is more cv-qualified than "cv1 T."
3 [Note: Function types (including those used in pointer to member func-
tion types) are never cv-qualified; see _dcl.fct_ . ]
4 A conversion can add cv-qualifiers at levels other than the first in
multi-level pointers, subject to the following rules:3)
Two pointer types T1 and T2 are similar if there exists a type T and
integer n>0 such that:
T1 is cv1,0 pointer to cv1,1 pointer to ... cv1,n-1 pointer to cv1,n T
and
T2 is cv2,0 pointer to cv2,1 pointer to ... cv2,n-1 pointer to cv2,n T
where each cvi,j is const, volatile, const volatile, or nothing.
The n-tuple of cv-qualifiers after the first in a pointer type,
e.g., cv1,1, cv1,2, ... , cv1,n in the pointer type T1, is called
the cv-qualification signature of the pointer type. An expression
of type T1 can be converted to type T2 if and only if the following
conditions are satisfied:
--the pointer types are similar.
--for every j>0, if const is in cv1,j then const is in cv2,j, and
similarly for volatile.
--if the cv1,j and cv2,j are different, then const is in every
_________________________
2) This conversion never applies to nonstatic member functions because
an lvalue that refers to a nonstatic member function cannot be ob-
tained.
3) These rules ensure that const-safety is preserved by the conver-
sion.
cv2,k for 0<k<j.
[Note: if a program could assign a pointer of type T** to a pointer
of type const T** (that is, if line //1 below was allowed), a pro-
gram could inadvertently modify a const object (as it is done on
line //2). For example,
main() {
const char c = 'c';
char* pc;
const char** pcc = &pc; //1: not allowed
*pcc = &c;
*pc = 'C'; //2: modifies a const object
}
--end note]
5 A multi-level pointer to member type, or a multi-level mixed pointer
and pointer to member type has the form:
cv0P0 to cv1P1 to ... cvn-1Pn-1 to cvn T
where Pi is either a pointer or pointer to member and where T is not a
pointer type or pointer to member type.
6 Two multi-level pointer to member types or two multi-level mixed
pointer and pointer to member types T1 and T2 are similar if there
exists a type T and integer n>0 such that:
T1 is cv1,0P0 to cv1,1P1 to ... cv1,n-1Pn-1 to cv1,n T
and
T2 is cv2,0P0 to cv2,1P1 to ... cv2,n-1Pn-1 to cv2,n T
7 For similar multi-level pointer to member types and similar multi-
level mixed pointer and pointer to member types, the rules for adding
cv-qualifiers are the same as those used for similar pointer types.
4.5 Integral promotions [conv.prom]
1 An rvalue of type char, signed char, unsigned char, short int, or
unsigned short int can be converted to an rvalue of type int if int
can represent all the values of the source type; otherwise, the source
rvalue can be converted to an rvalue of type unsigned int.
2 An rvalue of type wchar_t (_basic.fundamental_) or an enumeration type
(_dcl.enum_) can be converted to an rvalue of the first of the follow-
ing types that can represent all the values of its underlying type:
int, unsigned int, long, or unsigned long.
3 An rvalue for an integral bit-field (_class.bit_) can be converted to
an rvalue of type int if int can represent all the values of the bit-
field; otherwise, it can be converted to unsigned int if unsigned int
can represent all the values of the bit-field. If the bit-field is
larger yet, no integral promotion applies to it. If the bit-field has
an enumerated type, it is treated as any other value of that type for
promotion purposes.
4 An rvalue of type bool can be converted to an rvalue of type int, with
false becoming zero and true becoming one.
5 These conversions are called integral promotions.
4.6 Floating point promotion [conv.fpprom]
1 An rvalue of type float can be converted to an rvalue of type double.
The value is unchanged.
2 This conversion is called floating point promotion.
4.7 Integral conversions [conv.integral]
1 An rvalue of an integer type can be converted to an rvalue of another
integer type. An rvalue of an enumeration type can be converted to an
rvalue of an integer type.
2 If the destination type is unsigned, the resulting value is the least
unsigned integer congruent to the source integer (modulo 2n where n is
the number of bits used to represent the unsigned type). [Note: In a
two's complement representation, this conversion is conceptual and
there is no change in the bit pattern (if there is no truncation). ]
3 If the destination type is signed, the value is unchanged if it can be
represented in the destination type (and bit-field width); otherwise,
the value is implementation-defined.
4 If the destination type is bool, see _conv.bool_. If the source type
is bool, the value false is converted to zero and the value true is
converted to one.
5 The conversions allowed as integral promotions are excluded from the
set of integral conversions.
4.8 Floating point conversions [conv.double]
1 An rvalue of floating point type can be converted to an rvalue of
another floating point type. If the source value can be exactly rep-
resented in the destination type, the result of the conversion is that
exact representation. If the source value is between two adjacent
destination values, the result of the conversion is an unspecified
choice of either of those values. Otherwise, the behavior is unde-
fined.
2 The conversions allowed as floating point promotions are excluded from
the set of floating point conversions.
4.9 Floating-integral conversions [conv.fpint]
1 An rvalue of a floating point type can be converted to an rvalue of an
integer type. The conversion truncates; that is, the fractional part
is discarded. The behavior is undefined if the truncated value cannot
be represented in the destination type. [Note: If the destination
type is bool, see _conv.bool_. ]
2 An rvalue of an integer type or of an enumeration type can be con-
verted to an rvalue of a floating point type. The result is exact if
possible. Otherwise, it is an unspecified choice of either the next
lower or higher representable value. [Note: loss of precision occurs
if the integral value cannot be represented exactly as a value of the
floating type. ] If the source type is bool, the value false is con-
verted to zero and the value true is converted to one.
4.10 Pointer conversions [conv.ptr]
1 An integral constant expression (_expr.const_) rvalue of integer type
that evaluates to zero (called a null pointer constant) can be con-
verted to a pointer type. The result is a value (called the null
pointer value of that type) distinguishable from every pointer to an
object or function. Two null pointer values of the same type shall
compare equal. The conversion of a null pointer constant to a pointer
to cv-qualified type is a single conversion, and not the sequence of a
pointer conversion followed by a qualification conversion
(_conv.qual_).
2 An rvalue of type "pointer to cv T," where T is an object type, can be
converted to an rvalue of type "pointer to cv void." The result of
converting a "pointer to cv T" to a "pointer to cv void" points to the
start of the storage location where the object of type T resides, as
if the object is a most derived object (_intro.object_) of type T
(that is, not a base class subobject).
3 An rvalue of type "pointer to cv D," where D is a class type, can be
converted to an rvalue of type "pointer to cv B," where B is a base
class (_class.derived_) of D. If B is an inaccessible
(_class.access_) or ambiguous (_class.member.lookup_) base class of D,
a program that necessitates this conversion is ill-formed. The result
of the conversion is a pointer to the base class sub-object of the
derived class object. The null pointer value is converted to the null
pointer value of the destination type.
4.11 Pointer to member conversions [conv.mem]
1 A null pointer constant (_conv.ptr_) can be converted to a pointer to
member type. The result is a value (called the null member pointer
value of that type) distinguishable from any pointer to member not
created from a null pointer constant. Two null member pointer values
of the same type shall compare equal. The conversion of a null
pointer constant to a pointer to member of cv-qualified type is a sin-
gle conversion, and not the sequence of a pointer to member conversion
followed by a qualification conversion (_conv.qual_).
2 An rvalue of type "pointer to member of B of type cv T," where B is a
class type, can be converted to an rvalue of type "pointer to member
of D of type cv T," where D is a derived class (_class.derived_) of B.
If B is an inaccessible (_class.access_), ambiguous (_class.mem-
ber.lookup_) or virtual (_class.mi_) base class of D, a program that
necessitates this conversion is ill-formed. The result of the conver-
sion refers to the same member as the pointer to member before the
conversion took place, but it refers to the base class member as if it
were a member of the derived class. The result refers to the member
in D's instance of B. Since the result has type "pointer to member of
D of type cv T," it can be dereferenced with a D object. The result
is the same as if the pointer to member of B were dereferenced with
the B sub-object of D. The null member pointer value is converted to
the null member pointer value of the destination type.4)
4.12 Boolean conversions [conv.bool]
1 An rvalue of arithmetic, enumeration, pointer, or pointer to member
type can be converted to an rvalue of type bool. A zero value, null
pointer value, or null member pointer value is converted to false; any
other value is converted to true.
_________________________
4) The rule for conversion of pointers to members (from pointer to
member of base to pointer to member of derived) appears inverted com-
pared to the rule for pointers to objects (from pointer to derived to
pointer to base) (_conv.ptr_, _class.derived_). This inversion is
necessary to ensure type safety. Note that a pointer to member is not
a pointer to object or a pointer to function and the rules for conver-
sions of such pointers do not apply to pointers to members. In par-
ticular, a pointer to member cannot be converted to a void*.