Here is a structure in C, it contains one of several types of data, and we don't know which data is has the largest sizeof
:
typedef
struct {
union {
void *p_data;
size_t s_data;
};
int extra_stuff;
}
data_and_stuff;
Now I want the most efficient way to copy (any) data from one instance of the structure to another, like so:
void copy_data(data_and_stuff *from, data_and_stuff *to)
{
to->p_data = from->p_data ; \\ WRONG!
}
Of course, this is wrong, since maybe sizeof(size_t) > sizeof(void *)
.
Using preprocessor to define the largest member name, does not work, since I can't use sizeof()
there.
OK, I could give the union a name, yes (as commenters suggested) but I don't want to, because, this name will then be used in all sorts of code, it will make all code harder to understand.
So here's what I came up with, kind of ugly:
typedef
struct {
union {
void *p_data;
size_t s_data;
union { void * p; size_t s; } largest_data;
};
int extra_stuff;
}
data_and_stuff;
void copy_data(data_and_stuff *from, data_and_stuff *to)
{
to->largest_data = from->largest_data ;
}
Is there a better way?
EDIT: I guess, as John commented, my code is not guaranteed by the standard to work :) . I mean it "should", but, the standard explicitly says, to not read one member of the union, after writing to another.
CodePudding user response:
Here is a structure in C, it contains one of several types of data, and we don't know which data is has the largest
sizeof
It's not a question of knowing which union member has the largest size. You need to copy the member, if any, that actually has a value stored in it, or else the whole union (which you cannot do because it is anonymous), or else the whole structure.
If you don't know which union member has a value stored, then copying the whole structure is your only valid option. Thankfully, that's very easy to express ...
void copy_data(data_and_stuff *from, data_and_stuff *to) {
*to = *from;
}
... and the compiler is likely to produce code that handles that pretty efficiently.