The use of
const int i = ...;
to define a const object has been a source of confusion for a long time. It makes people think that;
const int* ptr = ...;
also defines a const pointer. That would be an erroneous conclusion. If you move the const a bit, it is less confusing.
int i = ...; // Defines i to be a non-const object
int const i = ...; // Defines i to be a const object
int* ptr = ...; // Defines ptr to be a non-const pointer to a non-const object
int const* ptr = ...; // Defines ptr to be a non-const pointer to a const object
int* const ptr = ...; // Defines ptr to be a const pointer to a non-const object
int const* const ptr = ...; // Defines ptr to be a const pointer to a const object
Coming to the issue of top level cv-qualifiers,
int const i = ...;
defines an object whose type is int and it has const qualifier.
int volatile i = ...;
defines an object whose type is int and it has volatile qualifier.
int const* ptr = ...;
defines an object whose type is int const* but it has no const or volatile qualifier. The second-level type, int has const qualifier but not the top level type.
int const* const ptr = ...;
defines an object whose type is int const* and it has const qualifier. The second-level type, int, also has const qualifier.
int * const ptr = ...;
defines an object whose type is int* and it has const qualifier. The second-level type, int, has no const qualifier.
More info:
Where is the definition of `top-level cv-qualifiers` in the C++11 Standard?
What are top-level const qualifiers?