Home > Blockchain >  how to best copy a union whose largest member is unknown
how to best copy a union whose largest member is unknown

Time:10-21

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.

  •  Tags:  
  • c
  • Related