Search code examples
c++language-lawyerundefined-behaviorconst-cast

Is casting a pointer to const pointer and cast back to the original type undefined?


I know casting a const pointer to non-const type might be undefined behavior, but what if the pointer is originally not 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;

Is there's any undefined behavior? If any, where do they happen? May the compiler assume that non_const_pi is casted from a const pointer and perform no modification?


Solution

  • No, this is not UB. Only when trying to modify a const object through a non-const access path results in UB. For this case, non_const_pi is pointing to a non-const object i in fact, then modifying through it is fine.

    There's an exact example in the standard, [dcl.type.cv]/4:

    ... any attempt to modify ([expr.ass], [expr.post.incr], [expr.pre.incr]) a const object ([basic.type.qualifier]) during its lifetime ([basic.life]) results in undefined behavior. [ Example:

    ...
    
    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