How to convert string to const unsigned char* without using reinterpret_cast (modern approach)

Viewed 1295

I have variable input type const std::string&:

const std::string& input

Now I need to convert this to const unsigned char* because this is the input of the function.

Unitl now I have correct code for converting:

reinterpret_cast<const unsigned char*>(input.c_str()) 

This works well, but in clang I got a warning:

do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

What is the correct way to change a string or const char* to const unsigned char*?

2 Answers

What is the correct way to change a string or const char* to const unsigned char*?

The correct way is to use reinterpret_cast.

If you want to avoid reinterpret_cast, then you must avoid the pointer conversion entirely, which is only possible by solving the XY-problem. Some options:

  • You could use std::basic_string<unsigned char> in the first place.
  • If you only need an iterator to unsigned char and not necessarily a pointer, then you could use std::ranges::views::transform which uses static cast for each element.
  • You could change the function that expects unsigned char* to accept char* instead.

If you cannot change the type of input and do need a unsigned char* and you still must avoid reinterpret cast, then you could create the std::basic_string<unsigned char> from the input using the transform view. But this has potential overhead, so consider whether avoiding reinterpret_cast is worth it.

Edit
Apparently type punning with an union is UB so definitely don't do this.
(Keeping the answer for posterity though!)


To strictly answer your question, there's this way:

void foo(const unsigned char* str) {
    std::cout << str << std::endl;
}

int main()
{
    std::string word = "test";
    //foo(word.data()); fails
    union { const char* ccptr; const unsigned char* cucptr; } uword;
    uword.ccptr = word.data();
    foo(uword.cucptr);
}

Is this any better than a reinterpret_cast? Probably not.

Related