请参阅以下内容:
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的结果?
(我知道上面的例子是不好的做法,糟糕的设计,可以用可变的方法解决 - 这不是重点)
答案 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打破的东西,但理论上它是可能的。