In a declaration T D where D has the form
* attribute-specifier-seqopt cv-qualifier-seqopt D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to T”. The cv-qualifiers apply to the pointer and not to the object pointed to. Similarly, the optional attribute-specifier-seq appertains to the pointer and not to the object pointed to.
const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; int i, *p, *const cp = &i;
declare ci, a constant integer; pc, a pointer to a constant integer; cpc, a constant pointer to a constant integer; ppc, a pointer to a pointer to a constant integer; i, an integer; p, a pointer to integer; and cp, a constant pointer to integer. The value of ci, cpc, and cp cannot be changed after initialization. The value of pc can be changed, and so can the object pointed to by cp. Examples of some correct operations are
i = ci; *cp = ci; pc++; pc = cpc; pc = p; ppc = &pc;
Examples of ill-formed operations are
ci = 1; // error ci++; // error *pc = 2; // error cp = &ci; // error cpc++; // error p = pc; // error ppc = &p; // error
Each is unacceptable because it would either change the value of an object declared const or allow it to be changed through a cv-unqualified pointer later, for example:
*ppc = &ci; // OK, but would make p point to ci because of previous error *p = 5; // clobber ci
— end example ]
[ Note: Forming a pointer to reference type is ill-formed; see [dcl.ref]. Forming a function pointer type is ill-formed if the function type has cv-qualifiers or a ref-qualifier; see [dcl.fct]. Since the address of a bit-field cannot be taken, a pointer can never point to a bit-field. — end note ]