stonebird
stonebird

Reputation: 339

const parameter problems

#include <iostream>

void f(const  int * & p)
{
    int i =0;
    i = p[0];
    std::cout << i << std::endl;
}

int main()
{
    int * p =new int[1];
    p[0] =102;
    f(p);
    return 1;
}

The gcc compiler gives error for this code:

prog.cpp: In function ‘int main()’:
prog.cpp:16: error: invalid initialization of reference of type ‘const int*&’ from expression of type ‘int*’
prog.cpp:5: error: in passing argument 1 of ‘void f(const int*&)’

But if I change the "f" function into

void f(const  int * const & p)

Everything is ok. Can somebody explain why const behaves this way? thanks.

Upvotes: 3

Views: 299

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254771

If the first conversion (int * to const int * &) were allowed, then you could write an evil function like this:

const int really_const[] = {1,2,3};

void evil(const int * & p)
{
    p = really_const;
}

int main()
{
    int not_const[3];
    int * p = not_const;
    evil(p);
    p[0] = 0;  // Whoops: modifying a const object
}

The second conversion is fine, since it prevents the function from modifying the pointer in this way.

Upvotes: 1

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507433

Going from int* to const int* requires creating a temporary const int* pointer and binding the reference const int*& to that temporary.

The Standard forbids doing that creating of a temporary for non-const references. You therefor need to make the reference const as you did your fix.

This is because non-const references mean "I want to change the argument that the caller passes using that reference parameter". But if the caller needs to convert their argument and ends up passing a temporary, the point of the reference is for naught, and so the Standard deems it an error to try and pass the temporary.

Upvotes: 10

Related Questions