In the following case I try to cast a pointer to a struct into a pointer to another struct (which has the same memory layout behind the scenes). I try to do this in a const correct way, however the compiler is complaining.
I looked at a similar issue but I need the constness to propagate and it doesn't work like described for me.
struct queue
{
// ...
};
typedef struct queue* queue_handle;
struct dummy_queue
{
// ...
};
struct queue_wrapper
{
auto get_queue() const -> queue_handle {
return reinterpret_cast<const queue_handle>(&d);
}
dummy_queue d;
};
int main()
{
queue_wrapper w;
w.get_queue();
}
Error:
<source>: In member function 'queue* queue_wrapper::get_queue() const':
<source>:17:16: error: 'reinterpret_cast' from type 'const dummy_queue*' to type 'queue_handle' {aka 'queue*'} casts away qualifiers
17 | return reinterpret_cast<const queue_handle>(&d);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I'm converting to a const pointer though (which gcc seems to misunderstand somehow). I do not need to change the pointer after returning it. How do I accomplish this conversion without errors?
CodePudding user response:
const queue_handle
applies the const
to the pointer type itself, not the pointed to type as you intent to.
I would suggest adding a const_queue_handle
alias to const queue*
if you are already using aliases for the pointers (whether or not that is a good idea is a matter of opinion) and then you can use that as template argument to reinterpret_cast
.
Also beware that even if the struct layout is identical, this is still undefined behavior territory. A compiler may assume that a pointer to one of the struct types won't alias one to the other and use that for optimization. You should probably at least compile everything with -fno-strict-aliasing
when doing this.