What book is that? I think that book is the only one that uses this definition.
According to that definition, the following is a "top-level const":
int * const foo;
In terms of parsing the meaning of the constness out of a declaration, it's suggested to read the declaration from right to left. Reading the above declaration from right to left, foo is a "const pointer to an int". Meaning, the int that foo points to can change but foo itself cannot.
The following is a "low-level const":
const int * foo;
Reading the declaration from right to left (sort of), foo is a "pointer to a constant int". Meaning, the int that foo points to cannot change but foo itself can.
Note that the previous declaration can be rewritten as:
int const * foo;
With the above declaration, the "reading the declaration from right to left" makes more sense. Moving the position of const between the '*'s in the declaration will not change its meaning. Moving a 'const' from the right side of a '*' to the left (and vice versa) changes the meaning of the declaration.
e.g.
1 2
|
const int * const * foo1;
int const * const * foo2;
|
In the above, the constness semantics of foo1 and foo2 are identical. They are both a "pointer to a constant pointer to a constant int". This means foo1 and foo2 can change but *foo1, **foo1, *foo2, and **foo2 cannot.
1 2
|
int * const foo1;
const int * foo2;
|
In the above, the constness semantics are different. foo1 is a "const pointer to an int" while foo2 is a "pointer to a constant int".