是否取消引用const_cast的指针ALWAYS会调用未定义的行为?

时间:2012-06-15 15:41:29

标签: c++

请参阅以下内容:

struct A
{
    std::string* get() const
    {
        //return const_cast<std::string*>(&m_pObj);
        return &const_cast<A*>(this)->m_pObj;
    }

    std::string m_pObj;
};

取消引用const_cast UB的this?是否有时间取消引用const_cast指针的常量调用UB的结果?

(我知道上面的例子是不好的做法,糟糕的设计,可以用可变的方法解决 - 这不是重点)

4 个答案:

答案 0 :(得分:9)

  

解除引用此UB的const_cast?是否有时间取消引用const_casting的结果,指针的常量不会调用UB?

并非总是如此,只有当对象 const时(A实例为const A x;,取消引用才会用于修改数据。如果它仅用于读取它将不是未定义的行为,如果对象不是const,(可能根本不是,可能是对非const对象的const引用)它不会是UB。

答案 1 :(得分:3)

不,如果引用的对象最初被声明为const ,那么它只是UB,您随后修改了强制转换获得的数据(§5.2.11/ 7和§7.1) .6.1 / 4)。以下是合法的:

A a;
a.get()->clear();

虽然这不是(因此是UB):

A const a;
a.get()->clear();

答案 2 :(得分:1)

没有。即:

  

5.2.2函数调用

     

5 [注意:一个函数可以更改其非const参数的值,但这些更改不会影响   参数的值,除非参数是引用类型(8.3.2);如果引用是a   const限定类型,const_cast需要用于抛弃constness以便修改   论证的价值。如果参数是const引用类型,则引入临时对象   需要(7.1.6,2.14,2.14.5,8.3.4,12.2)。此外,还可以修改非常量对象的值   通过指针参数。 - 后注]

然而,

  

5.2.11 Const cast

     

12 [注意:一些仅涉及cv资格变更的转换无法使用const_cast完成。   例如,不包括指向函数的指针之间的转换,因为这样的转换会导致   使用导致未定义行为的值。出于同样的原因,指向成员的指针之间的转换   函数,特别是从指向const成员函数的指针到指向a的指针的转换   非const成员函数,不包括在内。 - 后注]

答案 3 :(得分:0)

编译器可以自由地将const值存储在只读存储器中,可以自由地假设它在优化程序时永远不会改变。如果你抛弃了constness,你就会破坏与编译器的契约,所以技术上任何都可能发生。

实际上,编译器很少做一些会被const_cast-ing打破的东西,但理论上它是可能的。