Alex
Alex

Reputation: 3381

const_cast with two levels pointers

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.

Upvotes: 0

Views: 495

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385164

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.

Upvotes: 3

Related Questions