const_cast with two levels pointers

524 Views Asked by At

I want to do this conversion using C++ format, it works on the C way. but it fails when I try on C++ format.

It works!

void req_password(const void *data, size_t datalen)
{
    char *password_old = ((char **) data)[0];
    char *password_new = ((char **) data)[1];
    ...
}

It fails

void req_password(const void *data, size_t datalen)
{
    char *password_old = (const_cast<char **>(data))[0];
    char *password_old = (const_cast<char **>(data))[1];
    ...
}

error:

error: invalid const_cast from type 'const void*' to type 'char**'

So my doubt is, how could I do this conversion using the C++ way?

PS: This code is part from a API, I can't control the the input of data.

1

There are 1 best solutions below

2
Lightness Races in Orbit On BEST ANSWER

Don't.

If you are being given immutable data, then you are being given immutable data and that is the end of it!

First, here's what I suggest for maximum safety. Coercing data into its real type is a little tricky, alas:

void req_password(const void* data, size_t datalen)
{
    const char* password_old = (reinterpret_cast<const char* const*>(data)[0]);
    const char* password_new = (reinterpret_cast<const char* const*>(data)[1]);
    // ...
}

(I've actually added some constness in the above, as it seems to be the intent of having const void* in the first place.)

But, if you really want the strings to be mutable, then this is fine too:

void req_password(const void* data, size_t datalen)
{
    char* password_old = (reinterpret_cast<char* const*>(data)[0]);
    char* password_new = (reinterpret_cast<char* const*>(data)[1]);
    // ...
    // More obvious when you recall that `const void*` is actually `void const*`;
    // So:
    //   void  const*
    // becomes:
    //   char* const*
}

Notice how you don't even need const_cast here, because you're not modifying the thing that data points to: you are dereferencing it and getting its pointee.

Of course, ideally, data would point to a const std::string instance.