Iowa15
Iowa15

Reputation: 3079

C++ pointer to constant error

In a book I'm reading about C++ (C++ for Dummies) there is a section that says the following:

int nVar = 10;
int* pVar = &nVar;
const int* pcVar = pVar; // this is legal
int* pVar2 = pcVar;      // this is not

The book then goes on to explain:

The assignment pcVar = pVar; is okay -- this is adding the const restriction. The final assignment in the snippet is not allowed since it attempts to remove the const-ness of pcVar

My question is why is the last line not "legal". I don't understand how that impedes on the "const-ness" of pcVar. Thanks.

Upvotes: 2

Views: 219

Answers (7)

Collin
Collin

Reputation: 12287

It's just saying you can't create a non-const pointer from one that was const (at least, not without a const_cast).

The idea behind const is to have objects that cannot be modified by accident. Getting rid of const through a simple assignment would be quite dangerous, and would allow things like this:

void function(int* m) {
    *m = 20;
}

int main() {
    const int x = 10;
    //Oops! x isn't constant inside function any more, and is now 20!
    function(&x); 
}

Also, please check out The Definitive C++ Book and Guide List, it has lots of great references (C++ for dummies doesn't quite make the cut).

Upvotes: 2

user529758
user529758

Reputation:

const int *pcVar = pVar;
int *pVar2 = pcVar;

If pcVar is const int *, that implies that the int it points to may be const. (It isn't in this case, but it may be.) So if you assign pVar2, which is a non-const int *, it still allows the int it points to to be modified.

So if pcVar actually pointed to a const int, and you assign an int * to its address, then that int * pointer (pVar2 in this case) will allow you, by dereferencing, to modify it, and that's illegal (it's a constraint violation, so it invokes undefined behavior).

Upvotes: 3

Bijaya Bidari
Bijaya Bidari

Reputation: 341

The second line int pVar = &nVar; is error. g++ compiler says. error: invalid conversion from ‘int*’ to ‘int’

Upvotes: 1

andre
andre

Reputation: 7249

int * pVar = &nVar;
*pVar = 4 //is legal

const int* pcVar = pVar; // this is legal
*pcVar = 3 // this is not legal, we said the value was const thus it can not be changed

int* pVar2 = pcVar;      // this is not legal because...
*pVar2 = 3 -> *pcVar = 3 

Upvotes: 1

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

All the compiler knows is that pcVar is a const int*. That is, it points to a const int. Just because you made it point at a non-const int doesn't matter. For all the compiler knows, the pointer value could have changed at some point to point at a truly const int. Therefore, the compiler won't let you convert from a const int* back to a int* because it would be lying about the constness of the object it was pointing at.

For a simpler example, consider:

const int x;
const int* pc = x;
int* p = pc; // Illegal

Here, x truly is a const int. If you could do that third line, you could then access the const int object through p (by doing *pc) and modify it. That would be bad - x is const for a reason.

However, in the example you gave, since you know that the original object was non-const, you could use const_cast to force the compiler into trusting you:

int* pVar2 = const_cast<int*>(pcVar); 

Note that this is only valid if you know for certain that the object is non-const.

Upvotes: 2

QuentinUK
QuentinUK

Reputation: 3077

pcVar stays the same but pVar2 points to a non-const, const can be added but not taken away. The compiler does not look at the original nVar being non-const, only the attempt to assign a const to a non const. Otherwise you could get around the const and change the value.

Upvotes: 1

Michael Dorgan
Michael Dorgan

Reputation: 12515

Mixing const and non-const is illegal. The reason being, if you tell the compiler that one location's value is const and then use another pointer to modify that value, you have violated the const contract you made with the first element.

Upvotes: 1

Related Questions