I'm using a char
array in a struct to hold some generic data, like this (the input type may be a struct of unknown size so I can't just use a union; this code is heavily simplified):
typedef struct {
char buf[256];
} data;
void data_set_int(data *d, int a) {
memcpy(d->buf, &a, sizeof(a));
}
int data_get_int(data *d) {
int ret;
memcpy(&ret, d->buf, sizeof(ret));
return ret;
}
void data_set_float(data *d, float a) {
memcpy(d->buf, &a, sizeof(a));
}
float data_get_float(data *d) {
float ret;
memcpy(&ret, d->buf, sizeof(ret));
return ret;
}
int main(void) {
data d;
data_set_int(&d, 3);
int int_result = data_get_int(&d);
data_set_float(&d, 10.0f);
float float_result = data_get_float(&d);
return 0;
}
If I never attempt to write a float
and then read the data as an int
or vise versa, is this code well-defined in C(99)?
Compiling with GCC yields no warnings, and running the code gives the expected behavior (int_result == 3
, float_result == 10.0f
). Changing the memcpy
to a normal pointer dereference (int ret = *(int *)d->buf
) also works fine with no warnings.
All of the sources I've read on strict aliasing say that you can read any type as a char *
(so I think that means set
should be fine), but you cannot read a char *
as any other type (not so sure that get
is fine). Have I misunderstood the rule?