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...

Reply via email to