Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const_cast doesn't work c++? [duplicate]

Tags:

c++

const-cast

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 ?

like image 996
Khaledvic Avatar asked Jan 21 '12 15:01

Khaledvic


3 Answers

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.

like image 124
Peter Alexander Avatar answered Oct 06 '22 01:10

Peter Alexander


What you are doing is Undefined Behaviour. You cannot attempt to modify a variable that is const

like image 33
Tony The Lion Avatar answered Oct 06 '22 00:10

Tony The Lion


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.

like image 44
Jerry Coffin Avatar answered Oct 06 '22 02:10

Jerry Coffin