C 2018 6.7.6.1 1 says:
If, in the declaration “T D1”, D1 has the form
* type-qualifier-listopt D
and the type specified for ident in the declaration “T D” is “derived-declarator-type-list T”, then the type specified for ident is “derived-declarator-type-list type-qualifier-list pointer to T”. For each type qualifier in the list, ident is a so-qualified pointer.
This question is about the final sentence, but let’s work through the first one first.
Consider the declaration int * const * foo. Here T is int, D1 is * const * foo, type-qualifier-list is const, and D is * foo.
Then T D is int * foo, and that specifies “pointer to int” for the ident foo, so derived-declarator-type-list is “pointer to”. (There is no overt explanation of derived-declarator-type-list in the standard, but 6.7.8 3, discussing typedef, says it “is specified by the declarators of D.”)
Substituting these into the final clause of the first sentence tells us that T D1 specifies the type for foo is “pointer to const pointer to int”. Fine so far.
But then the final sentence tells us that for each type qualifier in the list (which is const), ident is a so-qualified pointer. So it says foo is a const pointer.
But it is not; we commonly interpret int * const * foo to declare foo to be a non-const pointer to a const pointer to int.
Is this a mistake in the standard or is there another interpretation for the final sentence?