L.Lawliet
L.Lawliet

Reputation: 319

Two different values at the same memory address

Code

#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;
}

Output

22 0x22ff74

33 0x22ff74

Why are there two different values at the same address?

Upvotes: 18

Views: 3862

Answers (7)

DharinS
DharinS

Reputation: 83

I had the same question (Why am I not able to modify the contents of const int even with const_cast<int*>?) . I think answered here wonderfully by everyone. Just adding the assembly output from compiler

This is my original code

const int y = 7;
int* a = new int;
a = const_cast<int*>(&y); 
*a = 8;
std::cout << (int)*(&y) << std::endl;

This is the assembly output

std::cout << (int)*(&y) << std::endl;
00381CB6  push        offset std::endl<char,std::char_traits<char> > (03813C5h)  
**00381CBB  push        7**  
00381CBD  mov         ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (03900ACh)]  
00381CC3  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (03900B8h)]  
00381CC9  mov         ecx,eax  
00381CCB  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (03900BCh)]  

So the compiler will just replace the const variables with its actual value during compile time.

Upvotes: 0

Rushikesh Patel
Rushikesh Patel

Reputation: 21

You can declare N as volatile, to force the compiler to fetch the current value from the variable's memory location.

volatile const int N = 22;

Upvotes: 1

Prasoon Saurav
Prasoon Saurav

Reputation: 92864

int * pN = const_cast<int*>(&N);
*pN = 33;

Your code invokes Undefined Behavior1 because you are modifying the content of a const qualified variable/object.

1) Undefined Behavior: Behavior, such as might arise upon use of an erroneous program construct or of erroneous data, for which the Standard imposes no requirements.[Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Upvotes: 4

GManNickG
GManNickG

Reputation: 503865

You get undefined behavior on the line *pN = 33;, because you're modifying a const value. Anything can happen. Don't do it.


Likely, though, your compiler simply optimized. In the line:

cout << N << '\t' << &N << endl;

It knows N is a constant expression with the value 22, so just changes the line to:

cout << 22 << '\t' << &N << endl;

And on your next line, you fetch the value at the address of N, which you "set" to 33. (But really, all you did was remove any guarantees about the state of your program.)

Upvotes: 15

Chubsdad
Chubsdad

Reputation: 25497

const_cast in your code, just hands over a pointer 'Pn' to 'N' through which 'N' can be modified. The address of 'N' remains the same as the handed over pointer 'Pn'

Upvotes: 0

bdonlan
bdonlan

Reputation: 231163

By stating that N is const, you have promised that you won't modify it. And then you go and modify it. This breaks one of the assumptions the compiler is making, and as a result, the program behaves incorrectly.

This is referred to as "undefined behavior" - after violating an assumption in the language, the behavior of the program is completely undefined. It need not have produced that output - it could've produced 33 for both, or 42, or crashed, or erased your hard drive, or summoned demons through your nasal passages. So, don't modify const values :)

Upvotes: 7

Eric Lippert
Eric Lippert

Reputation: 660098

Why are there two different datas at the same address?

There aren't. The compiler is allowed to optimize any mention of a const to be as though you had written its compile-time value in there.

Note that the compiler is also allowed to generate code that erases your hard disk when you run it if you do nasty tricks like writing to memory reserved for consts.

Upvotes: 26

Related Questions