I am trying to create a reference to a struct in an arbitrary block of memory pointed to by a void pointer. But I cant seem to work it out!
Given the example code below (tested on clang latest), I find that my reference is initialised to the address of the void pointer itself, rather than the value of the void pointer. Please help me understand what I dont!
#include <iostream>
int main(void)
{
struct Test
{
int a;
void * p;
unsigned x[10];
};
struct It
{
unsigned y[10];
};
Test t;
t.p = &t.x;
auto & s = reinterpret_cast<It &>(t.p);
std::cout << std::hex << "&t=" << &t << ", &t.p=" << &t.p << ", p=" << t.p << ", s=" << (void*)&s << std::endl;
}
I get the output:
&t=0x7ffd4fbac9f8, &t.p=0x7ffd4fbaca00, p=0x7ffd4fbaca08, s=0x7ffd4fbaca00
As you can see s references memory at the address of t.p. I was expecting the reference to be the same as the value of t.p.
To extend this further, the result is different if you change the cast line to:
auto a = t.p;
auto & s = reinterpret_cast<It &>(a);
Then you get:
&t=0x7ffc31e65578, &t.p=0x7ffc31e65580, p=0x7ffc31e65588, s=0x7ffc31e65570
Where the reference s is set to the address of t.
More of a learning question than anything but would be good to understand for the future.
reinterpret_cast<T &>(x)
is equivalent to *reinterpret_cast<T *>(&x)
(except the former doesn't respect overloaded &
, which makes it useful for implementing std::addressof
).
So if you had a different pointer type that can be dereferenced, you could do reinterpret_cast<It &>(*t.p)
. But since void *
can't be dereferenced, your only option is *reinterpret_cast<It *>(t.p)
.