A *cv-decomposition* of a type T
is a sequence of
cvi and Pi
such that T is
“cv0 P0 cv1 P1 ⋯ cvn−1 Pn−1 cvn U” for n>0,
where
each cvi is a set of cv-qualifiers, and
each Pi is
“pointer to”,
“pointer to member of class Ci of type”,
“array of Ni”, or
“array of unknown bound of”.
If Pi designates an array,
the cv-qualifiers cvi+1 on the element type are also taken as
the cv-qualifiers cvi of the array.
[ Example:
The type denoted by the *type-id* const int **
has two cv-decompositions,
taking U as “int” and as “pointer to const int”.
— end example ]
The n-tuple of cv-qualifiers after the first one
in the longest cv-decomposition of T, that is,
cv1,cv2,…,cvn, is called the
*cv-qualification signature* of T.

Two types T1 and T2 are *similar* if
they have cv-decompositions with the same n
such that corresponding Pi components are the same
and the types denoted by U are the same.

A prvalue expression of type T1 can be converted to type T2 if the following conditions are satisfied, where cvji denotes the cv-qualifiers in the cv-qualification signature of Tj:60

T1 and T2 are similar.

For every i>0, if const is in cv1i then const is in cv2i, and similarly for volatile.

If the cv1i and cv2i are different, then const is in every cv2k for 0<k<i.

[ Note: If a program could assign a pointer of type T** to a pointer of type const T** (that is, if line #1 below were allowed), a program could inadvertently modify a const object (as it is done on line #2). For example,

int 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 ]

[ Note: A prvalue of type “pointer to cv1 T” can be converted to a prvalue of type “pointer to cv2 T” if “cv2 T” is more cv-qualified than “cv1 T”. A prvalue of type “pointer to member of X of type cv1 T” can be converted to a prvalue of type “pointer to member of X of type cv2 T” if “cv2 T” is more cv-qualified than “cv1 T”. — end note ]

[ Note: Function types (including those used in pointer to member function types) are never cv-qualified ([dcl.fct]). — end note ]

These rules ensure that const-safety is preserved by the conversion.