conversion between const to nonconst

Anyone can explain why the second output is 0, rather than 1.

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
27
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int main() {
    
    const int x = 0;
    
    int const *py = &x;
    
    int *px = const_cast<int *>(&x);
    
    cout << *px << endl;        // output 0
    
    *px = 1;
    
    cout << x << endl;          // output 0, I don't understand
    cout << *px << endl;        // output 1
    cout << *py << endl;        // output 1
    
    cout << px << endl;         // 0x22ff24
    cout << py << endl;         // 0x22ff24
    
    return 0;
}
Cause what you are doing is illegal.
I understand we should not try to change the value of a constant. In this sense the code above is illegal.

But the code above is allowed by the C++ compiler. I can compile it without any warning or error.

Here I just use it as example to figure out what is the difference between x and *px. thanks,
But the code above is allowed by the C++ compiler. I can compile it without any warning or error.


The compiler will only complain if you have some kind of syntax error. It doesn't catch logic errors.

Here, the logic you're doing (modifying a constant) is undefined, which is why you get weird results.
thanks for your reply.

You mean since this kind of behavior (i.e., changing the value of a constant) is not defined inside the compiler, the consequence of this kind of action could be anything, and there is no way to judge what is "correct" or "incorrect". In this sense, any outcome of x could be said "correct" or "incorrect".

Am I right?
the consequence of this kind of action could be anything


Correct.
Since you declared x as "const", the compiler is allowed to assume that the value of x will not change. That said,
the compiler is free to replace memory accesses of x with the actual value, and in fact, not even allocate memory
for x.

However, as soon as you take the address of a variable, the compiler can no longer optimize it into a register --
it has to allocate memory for it. So you've got two different things going on. First, the compiler optimized the
line cout << x << endl; into cout << 0 << endl;. Second, line 11 caused the compiler
to allocate memory for x so it could take its address. References to x via pointer will now read the memory location.
Hence your two different answers.

Moral to the story: const_cast is very dangerous. In fact, the result of modifying a value which has had its constness
casted away with const_cast is undefined behavior according to the standard. const_cast<> really was only intended
to allow integration with legacy C functions that aren't const correct.
First, the compiler optimized the line cout << x << endl; into cout << 0 << endl;.

Can't you get around that problem by using the keyword volatile?
Last edited on
Can't you get around that problem by using the keyword volatile to get around that?


This sounds like a bad, bad idea. How about removing the const keyword from the original declaration if you have to modify it... :P

True, but it was just about the particular 'away-optimizing' problem.
Topic archived. No new replies allowed.