const_cast() - What's the difference?

Simple question.. why does this not work: (output is 50)

1
2
3
4
5
6
7
8
9
10
11
void changeConst(const int * p) {
	int * newP = const_cast<int *>(p);

	*newP = 150;
}

int main(int argc, char *argv[]) {
	const int A = 50;
	changeConst(&A);
	cout << A;
}


But this does? (Output is 150)

1
2
3
4
5
6
7
8
9
10
11
void changeConst(const int * p) {
	int * newP = const_cast<int *>(p);

	*newP = 150;
}

int main(int argc, char *argv[]) {
	const int *A = new int(50);
	changeConst(A);
	cout << *A;
}


Compiler is VS Express, if it matters.

Thanks!
Last edited on
This could be down to compiler optimization;

I think that when the compiler encounters the declaration:
const int A = 50; then it treats it like a constant
literal value and do not set aside storage for it.
and every occurrence of A will be replaced by the value 50.

However later on when you try to take it's address
changeConst(&A);
then the compiler does will make up a fake variable.

The changeConst(const int * p) will end up changing this fake variable ( but as we said earlier, the variable A has been optimised away and will always be substituted by the value 50 - refer to my first paragraph)

which iexplains why - this code
1
2
3
4
5
int main(int argc, char *argv[]) {
	const int A = 50;
	changeConst(&A);
	cout << A;
}

will print 50.
Last edited on
Because in the first code A is const so you are not allowed to modify it.
In the second code you allocate a non-const int so you are allowed to modify it.
I think you will find that my (slightly edited) answer is more correct, because if you check using a debugger - you will find that the debugger (doesn't matter whether you are using GDB or microsoft debugger)
will show the value of A as 150 BUT the cout statement will display 50.
(for the first code)
Both are correct. Because the language states that changing a const object, even through a const_cast pointer, is undefined behavior, compilers assume it won't ever happen and compile code such as "cout << 50;" in this case.
Peter, it works if it's

const int * A = new const int(50);

too. (If that's what you were referring to. And does that even make a difference, if anyone wants to comment on that?)

And ah, okay Cubbi. So really, compilers will usually just substitute out real constant objects? Are const pointers really the only way const_cast() is useful?

I obviously care way too much about the specifics, haha. I'm just trying to figure out the real use of const_cast().
Last edited on
The real use of const_cast is to change the const and volatile qualifications of a reference or of a pointer to data. That is all it does. It doesn't change the constness of an object, only of the access path.
bitani wrote:
Peter, it works if it's
const int * A = new const int(50);
too. (If that's what you were referring to. And does that even make a difference, if anyone wants to comment on that?)

That it's not allowed doesn't necessarily mean it will not "work". With most compilers it probably doesn't make a difference.

You should not have to use const_cast very often. If you have to use const_cast it's often a sign that you did something wrong. Only situation I have found const_cast useful is when having both a non-const version and a const version of a long function. With the help of const_cast we can avoid the code from being repeated in both functions. http://stackoverflow.com/questions/856542/elegant-solution-to-duplicate-const-and-non-const-getters
Topic archived. No new replies allowed.