Tor Rustad said:
This is really a question for Chris Torek...
Here is a simpler example:
$ cat const_cast.c
int main(void)
{
int **ppi;
const int * const *pcpci;
pcpci = ppi;
return 0;
}
$ cc -ansi -pedantic -Wall -W const_cast.c
const_cast.c: In function âmainâ:
const_cast.c:7: warning: assignment from incompatible pointer type
which requires a diagnostic in C (but perhaps not in C++, since no
const'ness is lost).
In C, two types are compatible if they are the same type (not only
if). A type qualifier (like const), change the type. When it comes to
pointer types, they are compatible, if they point to compatible
types.
If it were that simple, then assigning a char * to a const char *
would also be a constraint violation and it is not.
6.5.16.1 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[1] 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++
compiler.
Does anyone know the reason C chose this safe but restrictive rule?
Does it significantly simplify the compiler?
[1] Like this:
char *p;
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.