Reputation: 1933
I have a const uint8_t*
that I want to convert to a char*
for an interface that expects a char*
.
The easiest way to do this is with a C-style cast:
const uint8_t* aptr = &some_buffer;
char* bptr = (char*)aptr;
However, our internal style guide (which is based on the Google C++ Style Guide) bans C-style casts.
Another option is this monstrosity, which I find pretty unreadable:
char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
These other options I tried all failed to compile:
char* dptr = reinterpret_cast<char*>(aptr);
char* eptr = const_cast<char*>(aptr);
char* fptr = static_cast<char*>(aptr);
Is there any way I can perform this cast using a C++-style cast without nesting two separate cast operations?
Upvotes: 6
Views: 14837
Reputation: 20396
Another option is this monstrosity, which I find pretty unreadable:
char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
You might find it unreadable, but this is the idiomatic way to express this conversion in C++.
Here's what's important:
In total, those are two conversions that your code needs to make—removing the const-ness, and converting to a signed type. This demands that you make two explicitly expressed conversions, if you want to obey these coding practices. You may not agree with this principle, but your company/coding practices certainly do.
Of course, I don't think anything is stopping you from writing something like this:
char * convert_to_c_data_buffer(uint8_t const* ptr) {
return reinterpret_cast<char*>(const_cast<uint8_t*>(ptr));
}
char* dptr = convert_to_c_data_buffer(aptr);
Upvotes: 6
Reputation: 63830
Is there any way I can perform this cast using a C++-style cast without nesting two separate cast operations?
Not portably, no. There is no single "the type is wrong and the const is also wrong" cast.
Another option is this monstrosity, which I find pretty unreadable:
char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(ptr));
Do that.
Both C++ casts and your internal style guide are striving to make this look monstrous.
You can prevent the repetition of these casts by writing your own cast.
template< typename T >
char* awful_monster_cast( const T * ptr )
{
return reinterpret_cast<char*>(const_cast<T*>(ptr));
}
Upvotes: 9
Reputation: 238391
Is there any way I can perform this cast using a C++-style cast without nesting two separate cast operations?
Certainly. There is no need to nest those cast operations. Instead, you can use two separate expressions:
auto cuint = const_cast<uint8_t*>(aptr);
auto cptr = reinterpret_cast<char*>(cuint);
Upvotes: 0
Reputation: 180805
Is there any way I can perform this cast using a C++-style cast without nesting two separate cast operations?
If you want it done in a single line like char* foo = some_cast(source)
then no. The only cast that can remove const
is const_cast
so you need that plus an additional one to convert that now non const pointer into your source type. That leaves you with the monstrosity
char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
as the single line solution. This is a safety feature and makes it so it is painfully obvious you are removing constness.
Upvotes: 4