通过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
对象的错误,然后修改该对象将导致未定义的行为。如果我们想删除 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 aconst
object used to occupy before its lifetime ended results in undefined behavior.
和§7.1.6.1/ 4 (§7.1.6.1是
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 aconst
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屋!