通过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?

查看:101
本文介绍了通过const_cast删除const并调用不修改结果对象的非const函数是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,抛弃 const -ness应该谨慎,并且尝试删除 const -最初来自 const 对象的错误,然后修改该对象将导致未定义的行为。如果我们想删除 const -ness以便可以调用不修改对象的非const函数怎么办?我知道我们实际上应该标记这样的函数 const ,但是假设我使用的是不包含 const的错误代码版本可用。

I know that casting away const-ness should be done with care, and any attempt to remove const-ness from an initially const object followed by modifying the object results in undefined behaviour. What if we want to remove const-ness so that we may invoke a non-const function which doesn't modify the object? I know that we should actually mark such function const, but suppose I'm using a "bad" code that doesn't have the const version available.

总而言之,下面的代码是否安全?我的猜测是,只要您最终不修改对象就可以了,但是我不是100%确定。

So, to summarize, is the code below "safe"? My guess is that as long as you don't end up modifying the object you're ok, but I'm not 100% sure.

#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_cast 由C ++ 11标准的§3.8/ 9 定义(§3.8是对象生存期):

Undefined behavior with respect to const_cast is defined by the C++11 standard's §3.8/9 (§3.8 is “Object lifetime”):


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

Creating a new object at the storage location that a const object with static, thread, or automatic storage duration occupies or, at the storage location that such a const object used to occupy before its lifetime ended results in undefined behavior.

§7.1.6.1/ 4 (§7.1.6.1是 cv限定词”)

and §7.1.6.1/4 (§7.1.6.1 is “The cv-qualifiers”)


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

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

其他情况ds,如果您修改了 最初为 const 对象的对象,否则为 1

In other words, you get UB if you modify an originally const object, and otherwise 1not.

const_cast 本身不会引入UB。

§5.2.11/ 7 处还有一个非规范性注释,取决于类型。通过从 const_cast 获得的指针或引用进行写操作可能具有不确定的行为。

There is additionally a non-normative note at §5.2.11/7 that “depending on the type” a write through the pointer or reference obtained from a const_cast, may have undefined behavior.

此非规范性注释太笨拙了,以至于它有自己的非规范性脚注,这说明 const_cast 不仅限于放弃了 const的转化 -qualifier。

This non-normative note is so wooly that it has its own non-normative footnote, that explains that “const_cast is not limited to conversions that cast away a const-qualifier.”.

但是,尽管如此,我仍然无法想到任何写得很好或不依赖写的情况关于类型,即我无法理解此注释。这里还有另外两个答案,重点是写入一词。在本说明中,这是通过§3.8/ 9进入UB-land的必要条件,是的。对我来说,最棘手的是取决于类型,这似乎是该注释的重要部分。

However, still with that clarification I fail to think of any case where the write could be well-defined or not depending on the type, i.e., I fail to make sense of this note. Two other answers here focus on the word “write” in this note, and that's necessary to get into UB-land via §3.8/9, yes. The to me rather fishy aspect is the “depending on the type”, which appears to be the significant part of that note.

1)除了关于其他与非 const_cast 不相关的事情的UB规则发挥作用外,例如清空后来在除 typeid -expression外的其他上下文中取消引用的指针。

1) Except insofar as UB-rules about other non-const_cast-related things get into play, e.g. nulling a pointer that's later dereferenced in a context other than as typeid-expression.

这篇关于通过const_cast删除const并调用不修改结果对象的非const函数是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆