Why does the following give me a conversion error from double *** to const double***

c

Solution

If your C tag is to be believed, gcc generates a warning as the types differ for both your example and `const double * const * const * d`. In C++, it's an error in the OP code but the slap-const-everywhere approach is legal.

The reason the compiler warns you is that a pointer to a pointer ( or further indirection ) allows a pointer to be returned to the caller by modifying the location the parameter points to.

If the target of the pointer is declared as const, then the called function would expect the value it puts there to be treated as const on return.

A simpler case of passing a `T**` to a `const T**` which illustrates why this is an error would be:

void foo ( const char ** z )
{
    *z = "A";
}


int main (int nargs, char** argv)
{
    char*   z = 0;
    char**  d = &z;

    // warning in C, error in C++
    foo ( d );

    // bad - modifies const data
    z[0] = 'Q';
}

`const` in C means that the data won't change. `const` in C++ means the data won't change publicly - mutable data in a C++ object can change. A C compiler could optimise its code so that it caches some of the `const` data somewhere, but a C++ compiler can't do that due to possible mutablity, so has the weaker restriction that you can't return const data to non-const as above. So in C++, `double***` can be cast to `const double * const * const * d` as the extra `const`s prevent return of non-modifiable memory, but in C it generates a warning and possible errors if the compiler optimises repeated accesses to the memory elsewhere.

Problem

Why can't it convert `double ***` to `const double ***`? ``` void foo(const double ***d) { } int main (int args, char*[] args) { double ***d; /*initialize d */ foo(d); } ```

Original source