Why is the static_cast conversion invalid?

138 views Asked by At

I encountered a problem:

int main() {
    const void* p = NULL;
    const int** pp = static_cast<const int**>(p); // E0171 invalid type conversion (1)
    int* const* ppp = static_cast<int* const*>(p); // No error  (2)
}

Why is the conversion (1) here invalid, while the (2) is allowed?

2

There are 2 answers

0
Jan Schultke On BEST ANSWER

A static_cast is not allowed to remove const from the pointed-to type, only const_cast is allowed to do that.

(1) In the conversion:

// pointer to CONST void     pointer to MUTABLE pointer to const int
   const void *          ->  const int **

We are removing the const qualification from the pointed-to type. Without using const_cast to remove constness completely (which is probably not correct), we need to do:

// pointer to CONST void     pointer to CONST pointer to const int
   const void *          ->  const int * const *

// in code:
auto pp = static_cast<const int * const *>(p);

(2) The other conversion:

// pointer to CONST void     pointer to CONST pointer to int
   const void *          ->  int * const *

... is perfectly fine, because we are preserving the const-ness of what was pointed to.


Note: if you are having trouble with figuring out C/C++ type syntax, I recommend using cdecl+, an online tool which converts syntax to English prose.

0
Ammar Poursadegh On

In conversion (1), p is a const void* pointer, which means it points to a constant object of unknown type. You are trying to pass this pointer to a const int** pointer, which is a pointer to a pointer to a constant integer. However, this allows you to modify the constant integer via the const int** pointer, which is not allowed and violates object constancy.

In contrast, in conversion (2), you are trying to cast the same const void* pointer to a const* int* pointer that is a pointer to a constant pointer to a non-const integer. This is allowed because the pointer itself is constant, but the integer it points to is not. Therefore, you can safely cast p to this type without violating object stability.