invalid conversion from ‘const int*’ to ‘int*’

2020-04-19 08:26发布

问题:

I receive the following error

$ g++ test.cpp
test.cpp: In function ‘int test1(const int**, int)’:
test.cpp:11:14: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
         a=v[i];
              ^
test.cpp: In function ‘int main()’:
test.cpp:31:20: error: invalid conversion from ‘int**’ to ‘const int**’ [-fpermissive]
     cout<<test1(c,2)<<endl;
                    ^
test.cpp:4:5: error:   initializing argument 1 of ‘int test1(const int**, int)’ [-fpermissive]
 int test1(const int **v,int num)
     ^

when compiling the following code:

#include <iostream>
using namespace std;

int test1(const int **v,int num)
{
    int *a;
    int result=0;
    // do somethings ....
    for(int i=0;i<num;i++)
    {
        a=v[i];
        // do somethings ....
        result+=*a;
    }
    return result;
}

void test2(const int num)
{
    cout<<num<<endl;
}

int main()
{
    int a =5;
    int b =8;
    int **c;
    c=new int *[2];
    c[0]=&a;
    c[1]=&b;
    cout<<test1(c,2)<<endl;
    test2(a);
    delete [] c; 
    return 0;
}

i give an int to test2 which asks for const int and it is ok. however test1 does not accept int ** instead of const int **.

in the above code even typecast does not work:

a=(int *)v[i];

AFAIK, const means that I promise that I will not change the value of v and i didnt. however, the compiler gives me error.

回答1:

Just write

int const *a;  // or const int *a; which is the same.

...then const correctness will be preserved. The compiler complains because you try to assign v[i], which is an int const *, to int *, through which the elements that v promised would not be changed could be changed. Since you don't attempt to do that later, just use an int const* to reassure the compiler.

Note that a will remain a pointer variable (so you will be able to reassign it), only it will point to integer constants (which you cannot then change through a). To declare a constant pointer, you would write

int       *const a; // pointer constant to int variable,or
int const *const a; // pointer constant to int constant

The other error is similar in origin, although it is a bit more difficult to see why it is forbidden (since you're only adding const and don't try to take it away). Consider: Were an assignment from int** to int const ** allowed, you could write the following piece of code:

int const data[] = { 1, 2, 3, 4 }; // this is not supposed to be changed.

int *space;
int **p = &space;
int const **p2 = p; // this is not allowed. Were it allowed, then:

*p2 = data;
**p = 2;     // this would write to data.

And that would be bad, mkay. If you instead write

int test1(const int *const *v, int num)

Now v is a pointer (variable) to pointer constant(s) to int constant(s). Since *v is then constant, the loophole is closed, and the compiler will accept it.