const_cast

For the following program:
#include <iostream>
using namespace std;

int main() {
const int N = 22;
int* pN = const_cast<int*>(&N);
*pN = 33;
cout << N << '\t' << &N << endl;
cout << *pN << '\t' << pN << endl;
}
/*OUT
22 0xbf91cfa0
33 0xbf91cfa0 */

Don't understand how can the same memory address to hold two different values?
Last edited on
one location can't hold 2 values, of course.
the compiler has done something odd... possibly sub of N and 22, so that cout n is compiled as 'print 22'

which is fine because you have triggered undefined behavior by trying to force it to modify a constant.

look at the assembly your code generates to see what happened.
Last edited on
Hi Jonnin,
Thanks for the reply. You mean the compiler replace N with 22 for count? So actually, after the program execution, the value is 22 in 0xbf91cfa0? Thanks again!

A small change (make const N global):
#include <iostream>
using namespace std;
const int N = 22;

int main() {
int* pN = const_cast<int*>(&N);
*pN = 33;
cout << N << '\t' << &N << endl;
cout << *pN << '\t' << pN << endl;
}

This will generate a segmentation fault. What is the reason?
Interesting...it should not work either way, as (as jonnin pointed out) you're attempting to modify a constant. I can't explain why it works when you define the variable within main(), but...I'd strongly recommend against coding like this. FWIW...
Thanks, I am sure it is not good practice. Just curious to see the reason why it works this way. :-)
how can the same memory address to hold two different values?
This will generate a segmentation fault. What is the reason?

Attempted modification of a variable that was declared const renders the program undefined (the program has no meaning), and those effects are just two of the infinite number of possibilities that an undefined program can exhibit.

We can likely guess how exactly the code that the compiler produced led to these two effects (constant folding in the first case and page fault upon writing to .rodata in the second case), but it's generally meaningless trying to second-guess an undefined program.

(for fun, check out some of the examples where undefined programs compile in more puzzling ways at https://en.cppreference.com/w/cpp/language/ub#UB_and_optimization )

let me try to explain what you might be seeing, in beginner terms.
the compiler sees your code.
it swaps all the pure Ns with 22s.

so now it compiles this code:
1
2
3
4
5
6
int main() {
int* pN = const_cast<int*>(&N);
*pN = 33;
cout << (int)22 << '\t' << &N << endl;
cout << *pN << '\t' << pN << endl;
}


Do you see now what I was saying? The address of N (whatever that even MEANS since a pure constant has no address or memory location, its embedded in the instruction not the data area) has been hijacked and its location hacked to 33, but the compiler cleaned up the N and never USED the adders where "N" was supposed to be when referencing it ...

if the compiler had actually gone to address N and fetched the value in the cout statement, it would have shown 33 (incorrect behavior/undefined behavior).
Last edited on
Topic archived. No new replies allowed.