Question

I'm a bit confused what happened in the following code:


const int e = 2;

int* w = ( int* ) &e;          // (1) cast to remove const-ness
*w = 5;                        // (2)

cout << *w << endl;            // (3) outputs 5
cout << e << endl;             // (4) outputs 2

cout << "w = " << w << endl;   // (5) w points to the address of e
cout << "&e = " << &e << endl;

In (1), w points to the address of e. In (2), that value was changed to 5. However, when the values of *w and e were displayed, their values are different. But if you print value of w pointer and &e, they have the same value/address.

How come e still contained 2, even if it was changed to 5? Were they stored in a separate location? Or a temporary? But how come the value pointed by w is still the address of e?

Was it helpful?

Solution

As I said in my comment, once you modified the const value you are in undefined behaviour land, so it doesn't make much sense to talk about what is happening. But what the hell..

cout << *w << endl;            // (3) outputs 5
cout << e << endl;             // (4) outputs 2

At a guess, *w is being evaluated at runtime, but e is being treated as a compile time constant

OTHER TIPS

I suspect that you're tripping up the compiler. It doesn't expect you to play dirty tricks with e, so when it sees the line:

cout << e << endl;

It simply inserts the value 2 instead of looking for the actual value. You can verify (or disprove) this by looking at the disassembly of your program.

I'm guessing that the compiler has optimised the value output. It sees that e is const (so, it can't change -- in theory) and changes cout << e << endl; to cout << 2 << endl;. However, e still has to exist because it's used by w, so w correctly takes its address and modifies its value, but you don't see that in the cout.

Moral of the story -- only declare things const when you actually want to be const. Casting away constness is not a good idea.

The only thing I can think of is the compiler has some how optimised the code in such a way that any references to e are replaced with a value of 2 even though it assigns memory for e

so in effect (affect?) the line at comment (4) is 'optimized' to be

cout << "2" << endln;

I guess the compiler uses the constness to optimizes out the variable and insert a fixed value into the code.

This is covered by section [dcl.type.cv]/4 of the C++14 standard (earlier standards had similar text too):

Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.

e is a const object, and *w = 5; attempts to modify that object, therefore the result is undefined behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top