我知道将const指针强制转换为非const类型可能是未定义的行为,但是如果该指针最初不是const怎么办?
int i = 0;
int * pi = &i;
const int * const_pi = const_cast<const int*>(pi);
int * non_const_pi = const_cast<int*>(const_pi);
*non_const_pi = 0;
*non_const_pi = 1;
int j = *non_const_pi;
是否存在未定义的行为?如果有的话,它们在哪里发生?编译器是否可以假设non_const_pi
是从const指针强制转换的,并且不执行任何修改?
答案 0 :(得分:5)
我知道将const指针转换为非const类型可能是未定义的行为。
那是个误会。
常量广播指针绝不会导致未定义的行为。取消引用通过const
-将const_cast
指针指向const
对象而获得的非const
指针,即使原始对象用于读取,唯一模式。如果尝试写入对象,则为未定义行为。
int const i = 10;
int const* p1 = &i;
int* p2 = const_cast<int*>(p1); // OK.
std::cout << *p2; // Still OK.
*p2 = 20; // Not OK.
鉴于此,您的第二段代码完全可以。由于原始对象是非const
对象,因此没有未定义的行为。
来自The Standard, Section 5.2.11, Expressions/Const cast :
指针
const_cast
的结果引用原始对象。
答案 1 :(得分:4)
不,这不是UB。仅当尝试通过非常量访问路径修改const
对象时,才会导致UB。对于这种情况,实际上non_const_pi
指向非常量对象i
,然后对其进行修改就可以了。
标准[dcl.type.cv]/4中有一个确切的例子:
...任何修改尝试([expr.ass],[expr.post.incr], [expr.pre.incr])常量对象([basic.type.qualifier]) 寿命([basic.life])导致不确定的行为。 [示例:
... int i = 2; // not cv-qualified const int* cip; // pointer to const int cip = &i; // OK: cv-qualified access path to unqualified *cip = 4; // ill-formed: attempt to modify through ptr to const int* ip; ip = const_cast<int*>(cip); // cast needed to convert const int* to int* *ip = 4; // defined: *ip points to i, a non-const object