const_cast confusion

closed account (1yR4jE8b)
I've got the following program which uses a const_cast to modify a const int variable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

int main()
{
	const int x = 99;
	int* changeConst = const_cast<int*>(&x);

	*changeConst = 55;

	std::cout << "\nAddress of const value is: " << &x << '\n'
		<< "The non-const pointer points at: " << changeConst << " by means of const_cast.\n\n";
	
	if(&x == changeConst)
		std::cout << "The pointer points to a constant value.\n\n";
	else
		std::cout << "The pointer points to a different value...\n\n"; 
	
	std::cout << "Value of x: " << x << '\n'
		<< "Value of dereferenced pointer: " << *changeConst << "\n\n";
		
	if(&x == changeConst)
		std::cout << "The pointer still points to a constant value.\n\n";
	else
		std::cout << "The pointer now points to a different value...\n\n"; 
	
}


I get the following output:


Address of const value is: 0x7fff93b59acc
The non-const pointer points at: 0x7fff93b59acc by means of const_cast.

The pointer points to a constant value.

Value of x: 99
Value of dereferenced pointer: 55

The pointer still points to a constant value.


Can someone explain to me why, even though my pointer is pointing at x and when I dereference it I'm getting the value I supposedly changed it to but if I print x directly I get the old value?
const_cast does not allow you to change const values.

Manipulating a const value by casting away its constness is undefined behavior. You can do it if either you are certain that a reference or pointer refers to a non-const object or you are passing a const object to a (const-incorrect) function that will not modify the value.

There was a thread about this a few months ago. I can summarize its contents to this simple statement: Do not cast pointers to constants to pointers to variables.

On line 5, you're telling the compiler "I promise the value of x will never change from 99". The compiler can then use x as a symbolic constant, and instead of using a run time variable, it will evaluate x at compile time and replace it with 99. These two lines generate the exact same code:
1
2
std::cout <<x;
std::cout <<99;

(Note: The compiler may not actually do this. This is one possible optimization that the compiler may or may not implement. However, the compiler I'm talking about is known to do this.)

When you do &x, the compiler is forced to allocate a run time variable, because it's not possible to get the address of literal constants. The type of &x is 'const int *'. This is so the compiler won't let you do something like *&x=10;. However, the variable itself, like all data, can be modified. If you cast the pointer to (int *), the compiler will now let you modify the variable. It's possible to do *(int *)&x=10;.
However, this is a breach of the promise you made on line 5. You're modifying a variable you told the compiler would never change. The compiler isn't aware of this change because you're making it through a dereferenced pointer, and it will still understand a direct reference to 'x' as meaning '99'.
This is what causes the situation where (x!=*&x).

Pointers to constants exist so that the compiler can keep you from changing things you shouldn't. If you then go and strip this information, the compiler can no longer keep you from shooting yourself in the foot.
closed account (1yR4jE8b)
Thank you, I understand now.
Hi... I would like to add some thing to this discussion. your explanation is so good , but my doubt is . In this program the value of *&x is 99. I mean x = *&x. But *changeConst = 55. How can a address can have two different values.? .
The compiler is being smart enough to realize that (*&x) is the same expression as (x), so it's optimizing away the indirection. Try this:
1
2
3
4
5
	const int *y=&x;
	std::cout
		<< "Value of x: " << x << '\n'
		<< "Value of *&x: " << *y << '\n'
		<< "Value of dereferenced pointer: " << *changeConst << "\n\n";
Splitting the operation into two expressions is too much for any compiler.
What's up with all these const_cast questions lately????
This question was asked and answered over 3 weeks ago.
But there was one much more recently.
Thank You helois. understood.
Topic archived. No new replies allowed.