Why are the following values giving me conversion error from double *** to const double ***
If your C tag is to be considered, gcc generates a warning as the types are different for your example and const double * const * const * d
. In C ++, this is a bug in the OP's code, but the slap-const-all approach is legal.
The reason the compiler is warning you is because a pointer to a pointer (or further indirection) allows a pointer to be returned to the caller by changing the location the parameter points to.
If the target of the pointer is declared const, then the called function will expect that the value it calculates should be treated as a constant when returned.
The simplest case of passing T**
in const T**
, which illustrates why this is an error:
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 the data will not change. const
in C ++ means data won't change publicly - mutable data in a C ++ object can change. The AC compiler could optimize its code to cache some of the data const
somewhere, but the C ++ compiler cannot do that due to possible mutability, so it has a weaker limitation that you cannot return const data to non-const data as stated higher. Therefore, in C ++ it double***
can be added to const double * const * const * d
as the extra const
prevents unmodifiable memory from being returned, but in C it generates a warning and possible errors if the compiler optimizes memory re-access elsewhere.
source to share
The answer to your question can be found at http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
This means that you really should be using const double * const * const * d
.
This is also true for ** (pointer to pointer) for the same reasons.
This code also throws this error, and it's understandable why the compiler won't let you do it here:
double d = 0.0;
double * pd = &d;
const double ** ppd = &pd; // <--- Error
If you could do that, you could have a "const" pointer to the data (ppd), which you could change by changing the mutable value of d. This violates const, so the compiler won't let you do that.
source to share
Consider a d
pointer to a black box.
The compiler can add const to either itself d
or the black box, but not to the contents of the black box. So
void foo1(double ***d); /* ok, no casts needed */
void foo2(double *** const d); /* ok, no casts needed; const added to `d` itself */
void foo3(double ** const *d); /* ok, no casts needed; const added to the blackbox */
void foo4(double * const **d); /* oops, trying to change the insides of the blackbox */
void foo5(const double ***d); /* oops, trying to change the insides of the blackbox */
void foo6(double ** const * const d);
/* ok: d is a constant pointer to a constant blackbox */
source to share
With const double *** d, only the value of d is const . In C, the conversion from double a to const double * a is legal, and the conversion from double b to const double ** b (or further indirection) is not.
So to convert from double *** d to const double *** d2, you can do the following:
double *** d; const double * b = ** d; const double ** c = & b; const double *** d2 = & c;
Of course, the use of const double *** d remains dubious due to non-const directives.
source to share