Why are the following values ​​giving me conversion error from double *** to const double ***

Why can't he convert double ***

to const double ***

?

void foo(const double ***d)
{


}


int main (int args, char*[] args)
{
       double ***d;
       /*initialize d */

       foo(d);

}

      

+2


source to share


6 answers


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.

+8


source


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

.

+2


source


0


source


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.

0


source


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 */

      

0


source


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.

0


source







All Articles