5

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 ?

4

3 回答 3

12

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.

于 2012-01-21T15:42:39.080 回答
4

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

于 2012-01-21T15:43:09.033 回答
2

const_cast通常在/如果您收到const指向最初未定义为的对象的指针时使用const。如果(如您的情况)该对象最初被定义为const,则尝试修改它会导致未定义的行为。如果没有const_cast,编译器甚至不会让你尝试这样做(代码不会编译)。

然而,演员表告诉编译器你确定你知道你在做什么并且它真的很安全,所以编译器只需要闭嘴并按照你告诉它的去做,而不是像通常那样给出任何错误/警告消息做。不幸的是,在这种情况下,您正在做的事情并不安全,但是由于您已经告诉编译器关闭并执行此操作,因此您不会收到任何警告(至少对于大多数编译器而言)。

至于你应该做什么,归结为决定你k是否真的是 const 。如果你真的需要修改它,那么你需要将它定义为一个普通的(非const)变量。如果您想确保只有少量特定代码可以修改它,那么您可以/可以(出于一种可能性)将其设为小类私有:

class my_int { 
    int k;
public:
    my_int() : k(1) {}

    do_mod() { k = 10; }

    operator int() { return k; }
};

现在,do_mod可以k直接修改。其他代码可以像使用my_int对象一样使用对象int,但不能修改它的值——本质上,它就像一个右值。

公平地说,我可能应该指出,如果它真的尝试进行一些强制转换,其他代码可以修改k. 正如 Bjarne 所说,C++ 的保护机制旨在防止意外,而不是故意颠覆。

于 2012-01-21T16:36:54.203 回答