Indeed, declarators must have their postfix chain read first, left to right, then the prefix portions right to left. (Separately at each level of parenthesization, if any, working inside out.)
There is no choice about where to put const inside a declarator; the position affects the nesting level which alters the semantics. So there is no debate to be had there.
Note that in declarators, the const is necessarily to the left of the thing it qualifies, so why would we put it to the right of int:
int ** const ptr;
^^^ this is what is const
int * const *ptr;
^^^^ this is what is const
const int **ptr;
^^^ ^^^^^ these two are const
In the canonical specifier order, nothing to the left of const is tainted by const:
extern const int **ptr;
^^^ ^^^^^^ const and const
^^^^^^ unrelated to const
For the best possible consistency, imagine const to be pissing, while the wind is blowing left to right.
Your third example could just as easily and correctly be:
int const **ptr;
^^^^^ this is what is const
True, it is a special case when there is more than one item in the declarator list as to how const applied, but that by itself is secondary to where const goes.
Const qualifies the object. Whether the const is applying to the "int" in some way or is an independent type specifier that applies to each declarator is pretty philosophical. I say it's the latter. The fact is, the very allowance of a cv qualifier in the specifier list introduces an inconsistency or imbalance.
Ultimately this is one of the ultimate bikeshedding argument. There's no right answer, and appeals to spoken language aren't particularly compelling when bikeshedding C of all languages. This isn't AppleScript.
I'm not even terribly interested in this particular point. I'm more interested in quashing the notions that bikeshedded opinions of language syntax have some divine providence. It's just bullshit.
We're then missing that the const qualification is applying to the int type.
Also, declarations can have multiple declarators.
int const *p, volatile **q[3]; // syntax error! not how it works
This isn't bike-shedding. The shed has already been painted. There is a right answer which is not to make your code look weird just because the standard allows it.
No "int const", no i[array] instead of array[i], no deceptive trompe d'oeil nonsense like:
int* p, q;
You will not solve any issue in C programming by swapping around declarators.
When we write code, stuff that looks weird should signal a bug. When bug-free code looks weird, that is a distracting false positive that grabs my attention for no reason. Don't add gratuitous weird.
There is no choice about where to put const inside a declarator; the position affects the nesting level which alters the semantics. So there is no debate to be had there.
Note that in declarators, the const is necessarily to the left of the thing it qualifies, so why would we put it to the right of int:
In the canonical specifier order, nothing to the left of const is tainted by const: For the best possible consistency, imagine const to be pissing, while the wind is blowing left to right.