I'm not sure how you managed to obtain that "makes only difference to
CLANG" result in your experiments. A simple code sample
void foo(const int *const *p) {}
int main(void) {
int **p = 0;
foo(p);
}
immediately demonstrates that GCC and Clang in '-pedantic-errors'
mode both issue an "error" message for this code (and abort
compilation).
Both compilers behave identically in this regard. This
applies to
your original code as well.
Now, the portions of C language standard that make it a hard error are:
* List of constraints for "Simple assignment"
https://port70.net/~nsz/c/c11/n1570.html#6.5.16.1p1
(which also apply to initialization), and
* "Type qualifiers" section, which explains how qualifiers affect type
compatibility
https://port70.net/~nsz/c/c11/n1570.html#6.7.3p10
(The above links refer to an older version of the document, but it is
good enough for our purposes).
The former states that you can only assign to each other pointers to
"qualified or unqualified versions of _compatible_ types". The latter says
that in order for two types to be compatible wrt qualifiers, both types
have to be _identically_ qualified.
That "qualified or unqualified versions" part is what permits you to convert
'T *' to 'const T *', i.e. there's some freedom wrt qualifiers at the very
first level of indirection. But there's no such freedom at deeper levels
of indirection: all qualifiers at the deeper levels have to be absolutely
positively 100% identical. Otherwise, the constraint is violated,
which is a hard error.
I'm not sure what specific "C FAQ" you are referring to here, but it is
besides the point anyway. FAQs are not normative. Language standard is.
Finally, there's no room for "little bit early" of any kind here. The
issue in question is well-known and already researched to death. It is
anscient, meaning that "early" is not really an appropriare word here.
And it is really not a debate. When I posted my original answer, the
matter has been closed. All we are doing at this point
is trying to
help you understand this issue, which has obviously proven to be a bit
surprising
to you.
--
Best regards,
Andrey
P.S. Yes, the 'void *' trick does work as a workaround here. Albeit it is
a fairly inelegant one...