c++standardsimplicit-conversionconst-cast

`const_cast`, top-level const and lvalue-to-rvalue conversions


Let's assume we have a simple piece of code,

int main() {
  int x = 5;
  int* const y = &x;
  const_cast<int*>(y);
}

Is my assumption that a lvalue-to-rvalue conversion happens inside the const_cast expression, to read the value of y, correct?

If it is... Would it then be correct to say that const_cast can never be used to cast away a top-level const qualifier, since it's removed implicitly during this lvalue-to-rvalue conversion? And what about adding top-level const qualifiers? I see it's possible, but are we really adding a top level const when we do something like:

int main()
{
    int x = 5;
    int* y = &x;
    const_cast<int* const>(y);
}

...this clearly won't add the top level const qualifier to y... and we could just do the same implicitly with an assignement to const pointer. So what is this needed for?


Solution

  • Would it then be correct to say that const_cast can never be used to cast away a top-level const qualifier, since it's removed implicitly during this lvalue-to-rvalue conversion?

    Informally, "lvalue-to-rvalue conversion" means something like "the value of the object is read".

    const_cast only needs to do it when casting to a non-reference, so casting to a reference wouldn't peform it, I believe, so constness wouldn't be stripped automatically.

    Also note that prvalues of class and array types can be const, unlike scalars.

    And what about adding top-level const qualifiers?

    Sure, casting to a const T &. Remember that expressions can't have reference types, so const_cast<const T &>(...) returns a top-level const lvalue of type const T.

    are we really adding a top level const when we do something like: const_cast<int* const>(y);

    No, not in this case. You have to cast to a reference.