If it were that simple, then assigning a char * to a const char *
would also be a constraint violation and it is not.
18.104.22.168 Simple assignment
Says that (amongst other things):
-- both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;
So assignment (and, by extension, parameter passing) is allowed to "add
qualifiers" to the pointed-to type (but not to the type pointed-to by
the pointed-to type).
As far as I can tell, this rule is somewhat arbitrary and is intended,
presumably, to simplify the compiler's job. It (or something like it)
is required because without it a constraint-free program could modify
a const object but at least one other language took the view that
all "safe" assignments would be allowed. Thus the OP's original
example (with const at every level) causes not a peep from a C++
Does anyone know the reason C chose this safe but restrictive rule?
Does it significantly simplify the compiler?
 Like this:
const char foo = 'F';
const char **cp = &p; /* Innocent at first glance */
*cp = &foo;
*p = 'B'; /* Pow! */
This (correctly) raises the alarm from both C and C++ compiler, but
changing the key line to:
const char *const *cp = &p; /* Entirely safe. */
causes C++ to complain only at the now obviously illegal line following
where a now const object is being modified. Both this new line and
the following one are constraint violations as far as C is concerned.