繁体   English   中英

通过const_cast删除const并调用不修改结果对象的非const函数是否安全?

[英]Is it safe to remove const via const_cast and invoke a non-const function that does not modify the resulting object?

我知道应该小心地抛弃const -ness,并且任何从初始const对象中删除const -ness然后修改对象的尝试都会导致未定义的行为。 如果我们想删除const -ness以便我们可以调用一个不修改对象的非const函数,该怎么办? 我知道我们实际上应该标记这样的函数const ,但是假设我使用的是一个没有const版本的“坏”代码。

那么,总结一下,下面的代码是“安全的”吗? 我的猜测是,只要你没有最终修改对象你就可以了,但我不是百分百肯定。

#include <iostream>

struct Foo
{
    void f() // doesn't modify the instance, although is not marked const
    {
        std::cout << "Foo::f()" << std::endl;
    }
};

int main()
{
    const Foo foo;
    const_cast<Foo&>(foo).f(); // is this safe?
}

这个特定的例子恰好是安全的(具有良好定义的行为),因为没有写入声明为const的对象。

我们在[dcl.type.cv]中有这个:

除了可以修改声明为mutable (7.1.1)的任何类成员之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。

[expr.const.cast]中有一条注释(非规范性),其中说明:

[注意:根据对象的类型,通过指针,左值或指向数据成员的指针的写入操作会导致const-qualifierconst_cast产生未定义的行为(7.1.6.1)。 - 尾注]

尝试在const_cast [可能]导致未定义的行为后修改对象或写入操作。 在这里,我们没有写操作。

关于const_cast未定义行为由C ++ 11标准的§3.8/ 9定义 (§3.8是“对象生存期”):

在创建一个存储位置的新对象const静态,螺纹,或自动存储持续时间对象占用或者,在这样的存储位置const用来占据其生命周期结束导致不确定的行为之前的对象。

§7.1.6.1/ 4 (§7.1.6.1是“ cv-qualifiers ”)

除了可以修改任何声明为mutable类成员(7.1.1)之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为。

换句话说,如果修改原始const对象,则获得UB,否则为1

const_cast本身不会引入UB。


§5.2.11/ 7中还有一个非规范性的注释,“取决于类型”,通过从const_cast获得的指针或引用进行写入,可能具有未定义的行为。

这种非规范的音符是如此毛茸茸的,它有它自己的非规范性的注脚,那解释说:“ const_cast不限于抛弃一个转换const -qualifier。”

然而,仍然有了这个澄清,我没有想到任何情况下写入可以明确定义或不取决于类型,即,我没有理解这个说明。 这里的另外两个答案集中在本说明中的“写”一词,并且必须通过§3.8/ 9进入UB-land,是的。 对我来说相当可疑的方面是“取决于类型”,这似乎是该注释的重要部分。


1)除非关于其他非const_cast相关事物的UB规则发挥作用,例如使以后在除了作为typeid -exression之外的上下文中解除引用的指针归零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM