I have a structure which aims at storing user defined data (i.e. from a plugin). It has a such a char[]
with a given maximum size to store that data.
struct A
{
// other members omitted
// data meant to be type punned, only contains PODs
char data[256];
};
Then there's a sample user structure that has a static function to cast itself from A
.
struct B
{
int i;
double d;
static B& FromA_ref(A& a)
{
// static_assert that sizeof(B) < sizeof(A::data)
return * reinterpret_cast<B*>(a.data);
}
};
I compile with g++ -O3 -std=c++0x -Wall -o test test.cpp
(GCC 4.6.1).
This triggers a dereferencing type-punned pointer will break strict-aliasing rules
warning. I thought that would be ok since I have used a char[]
as storage which I thought would follow the same rules as char*
. I find it strange that it doesn't. Don't you ? Well, ... I can't change it right now, so let's move on.
Now let's consider the following method:
struct B
{
....
static B* FromA_ptr(A& a)
{
// static_assert that sizeof(B) < sizeof(A::data)
return reinterpret_cast<B*>(a.data);
}
}
Since I am not dereferencing anything here GCC doesn't output any warning. Neither does it when I use my pointer to B
later on.
A a;
auto b = B::FromA_ptr(a);
b->i = 2; // no warnings.
But is it safe to do so ? I feel like I have been working my way around the problem rather than solving it. For me ->
is still dereferencing the variable somehow.
Alternatively, are there any better way to achieve the effect ? I.E. get a modifiable reference (or pointer) casted from a storage inside another struct ? (Union won't work since the set of types stored are not known when A
is defined and some may be added via plug-ins, memcpy
will force me to copy the data back and forth though it seems to be the only safe way so far)