4 Standard conversions [conv]

4.5 Qualification conversions [conv.qual]

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 ([basic.type.qualifier]), and each Pi is “pointer to” ([dcl.ptr]), “pointer to member of class Ci of type” ([dcl.mptr]), “array of Ni”, or “array of unknown bound of” ([dcl.array]). 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 cvij denotes the cv-qualifiers in the cv-qualification signature of Tj60:

  • T1 and T2 are similar.

  • For every i > 0, if const is in cvi1 then const is in cvi2, and similarly for volatile.

  • If the cvi1 and cvi2 are different, then const is in every cvk2 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.