Reputation: 3079
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
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
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
Reputation: 341
The second line int pVar = &nVar; is error. g++ compiler says. error: invalid conversion from ‘int*’ to ‘int’
Upvotes: 1
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
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 const
ness 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
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
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