Modifying a const through a non-const pointer

我的未来我决定 提交于 2019-11-26 04:28:30

问题


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 &lt&lt *w &lt&lt endl;            // (3) outputs 5
cout &lt&lt e &lt&lt endl;             // (4) outputs 2

cout &lt&lt \"w = \" &lt&lt w &lt&lt endl;   // (5) w points to the address of e
cout &lt&lt \"&e = \" &lt&lt &e &lt&lt 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?


回答1:


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




回答2:


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.




回答3:


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.




回答4:


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;



回答5:


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




回答6:


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.



来源:https://stackoverflow.com/questions/2508605/modifying-a-const-through-a-non-const-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!