The type of &n
is int const *
.
The type of *pp2
is int const *
.
The const
qualifies the pointee, not the pointer, in this case.
So assigning one to the other is perfectly valid. The comment you quoted may be wrong, and should perhaps say:
// Which means we can't use **pp2 to modify the value of the
// variable whose address is stored in *pp2.
To elaborate :
int *p1;
The above creates a variable named p1
that can store the address of an int
. It's type is int*
. This statement doesn't initialize it, and so it hold an unspecified address (the value it can hold).
const int **pp2= &p1;
The above attempts to create and assign to a variable name pp2
. It's type is int const **
and the statement tries to assign it the address of p1
. Now the expression &p1
has the type int **
, and the assignment fails, since the const
qualifications mismatch.
As you can see, the code is in complete alignment with the (possibly corrected) statements.