是否将指针转换为const指针并转换回未定义的原始类型?

Tuf*_*der 1 c++ const-cast undefined-behavior language-lawyer

我知道将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;
Run Code Online (Sandbox Code Playgroud)

有没有未定义的行为?如果有的话,它们在哪里发生?编译器可以假定它non_const_pi是从const指针强制转换的,并且不执行任何修改吗?

son*_*yao 5

不,这不是UB。const仅当尝试通过非常量访问路径修改对象时才会导致 UB。对于这种情况,实际上non_const_pi指向一个非常量对象,然后通过它进行修改就可以了。i

\n\n

标准中有一个确切的示例[dcl.type.cv]/4

\n\n
\n

...在其生命周期内修改 ([expr.ass], [expr.post.incr],\n [expr.pre.incr]) const 对象 ([basic.type.qualifier]) 的任何尝试 ( [basic.life]) 导致未定义的行为。[\xe2\x80\x89示例:

\n\n
...\n\nint i = 2;                              // not cv-qualified\nconst int* cip;                         // pointer to const int\ncip = &i;                               // OK: cv-qualified access path to unqualified\n*cip = 4;                               // ill-formed: attempt to modify through ptr to const\n\nint* ip;\nip = const_cast<int*>(cip);             // cast needed to convert const int* to int*\n*ip = 4;                                // defined: *ip points to i, a non-const object\n
Run Code Online (Sandbox Code Playgroud)\n
\n


R S*_*ahu 5

我知道将const指针转换为非const类型可能是未定义的行为。

那是个误会。

常量广播指针永远不会导致未定义的行为。解引用非const通过的方式获得指针const_cast-ing一个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.
Run Code Online (Sandbox Code Playgroud)

鉴于此,您的第二段代码完全可以。由于原始对象是非const对象,因此没有未定义的行为。

标准,第5.2.11,表达式/常量投

指针的结果const_cast引用原始对象。