问题
I have the following code :
const int k=1;
int *p=const_cast<int *>( &k);
cout<<"k before="<<*p<<endl;
*p=10;
*const_cast<int *>( &k)=12;
cout<<"k after="<<k<<endl;
the output was :
k before=1
k after=1
why doesn't const cast work here ?
回答1:
const_cast
is normally used when/if you receive a const
pointer to an object that wasn't originally defined as const
. If (as in your case) the object was originally defined as const
, attempting to modify it causes undefined behavior. Without the const_cast
, the compiler won't let you even try to do that (the code won't compile).
A cast, however, tells the compiler you're sure you know what you're doing and it's really safe, so the compiler just needs to shut up and do what you told it instead of giving any error/warning messages like it might usually do. Unfortunately, in this case what you're doing is not really safe, but since you've told the compiler to shut up and do it, you won't get any warning about it (at least with most compilers).
As to what you should do, it comes down to deciding whether your k
is really const or not. If you really need to modify it, then you need to define it as a normal (non-const
) variable. If you want to ensure that only a small amount of specific code can modify it, then you could/can (for one possibility) make it private to a small class:
class my_int {
int k;
public:
my_int() : k(1) {}
do_mod() { k = 10; }
operator int() { return k; }
};
Now, do_mod
can modify k
directly. Other code can use a my_int
object as if it were an int
, but can't modify its value -- in essence, it acts like an rvalue.
In fairness, I should probably point out that if it really tries by doing some casting, other code can modify the value of k
. As Bjarne has said, C++'s protection mechanism is intended to prevent accidents, not intentional subversion.
回答2:
const_cast
causes undefined behaviour if you cast away const
then write to the value. Not doing anything is valid behaviour, as you have seen here.
In your particular example, what has likely happened is that the compiler sees that k
is declared with the const
storage class, knows that it can't (legally) change, and replaces
cout<<"k after="<<k<<endl;
with
cout<<"k after="<<1<<endl;
If you turn off optimisations you may (or may not) get a different result.
The very reason that casting away const
invokes undefined behaviour is so that the compiler is free to do optimisations like this. If const
variables could be freely cast to non-const
variables and written to, then const
would be absolutely meaningless to the compiler.
回答3:
What you are doing is Undefined Behaviour. You cannot attempt to modify a variable that is const
来源:https://stackoverflow.com/questions/8954260/const-cast-doesnt-work-c