const_cast对这个指针的未定义行为是什么?

时间:2014-08-15 23:54:02

标签: c++

在另一个问题中,我遇到了这段代码:

Real StatData::mean(Real trim) const
{
   // trim, pun not intended
   const_cast<StatData&>(*this).items.sort();
   // trim
}

cppreference还有一个关于page的例子:

struct type {
    type() :i(3) {}
    void m1(int v) const {
        // this->i = v;                 // compile error: this is a pointer to const
        const_cast<type*>(this)->i = v; // OK
    }
    int i;
};

除了明显的问题,为什么这是实用的,它是否不安全?创建的对象是否为const是否重要,更重要的是,this指针是否可以保护未定义的行为,因为它只为那一个函数标记为const

2 个答案:

答案 0 :(得分:9)

  

创建的对象是否与const无关

是。如果对象是非const创建的,那么无论您做什么,const_cast都是安全的。只是一个坏主意(因为通常你不会知道对象的创建非 - const)。

  

这个指针可以防止未定义的行为,因为它只标记了那个函数的const?

这确实是错误的问题,但问题是,在您尝试修改const对象之前,您是安全的。这意味着const_cast本身是完全合法且定义明确的,但如果items.sort()修改了内容(我们必须假设它),那么 操作会导致UB。< / p>

最后,虽然你试图在你的问题中掩盖这一点,但实际情况实际上是这个场景的基础:即使在这个看似特殊的情况下,代码是安全的也很难保证。所以,不要这样做。尽管你出于这个问题的目的而试图将其抽象出来,但我不能强调这一点。

答案 1 :(得分:6)

const_cast本身从不未定义的行为。它可能是不正确的,即无法编译。但是如果它是格式良好的(即可编译的)那么它本身就不会产生不确定的行为。

您之后使用const_cast帮助获得的[非常量]访问路径可能会触发未定义的行为。但这是一个完全不同的故事,与const_cast没有直接关系。

到目前为止您发布的代码示例不足以判断它们是否表现出未定义的行为。这一切都取决于外部因素:被修改的对象是否真的被声明为const。尝试修改const对象会触发未定义的行为。

例如,对于上面的type类,此代码会触发UB

const type t;
t.m1(42);  // <- undefined behavior

虽然这个没有

type t;
t.m1(42);
assert(t.i == 42);