Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could one copy union simple members with memcpy?

I'm not quite sure about standard quotes about memcpy and union trivial members.

Consider the code:

struct Test{
    union
    {
        void(*function_p)(void*);
        void(*function_p_c)(const void*);
    };
    Test(const Test &other)
    {
        using std::memcpy;
        memcpy(&function_p, &other.function_p, sizeof(function_p)); //?
        memcpy(&function_p_c, &other.function_p_c, sizeof(function_p_c)); //??
    }
};

int main(void)
{
    Test t1; t1.function_p = NULL; //let it be NULL for c++98 sake
    Test t2(t1); // is it safe? does this set new active member of union?

    return 0;
}

So the one question leads to another:

  • is code above safe? or is it UB with second/first memcpy depending on which union member user have touched? is it overkill to call memcpy for both members?

  • if it is not safe then how could I implement copy constructor without some flag-of-active-union-member?

like image 372
Alexander G. Avatar asked Aug 26 '19 07:08

Alexander G.


1 Answers

What you are doing with two memcpy is undefined behavior.

The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.

other has only function_p as active and the second memcopy triggers undefined behavior.

like image 197
Oblivion Avatar answered Nov 02 '22 01:11

Oblivion