Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know that which variable from Union is Used?

Tags:

c

unions

If I declare a Union as:

union TestUnion
{
    struct 
    {
      unsigned int Num;
      unsigned char Name[5];
    }TestStruct;
    unsigned char Total[7];
};

Now, How can I know that whether Total[7] is used or TestStruct is used?

I am using C! I was revisiting unions and structures and this question came to my mind. "sizeof" can't be used as both are of same size i.e. 7 bytes. (And Here comes another question)

When I filled only "Total" with a Character 'a' and Tried sizeof(TestUnionInstance), it returned 12 (Size of Char is 1 byte, Right?). So I isolated the structure from it and found that Size of Structure is 12 bytes not 5+2=7 bytes.... Strange!! Anybody can explain??

P.S. I am using Visual Studio 2008.

like image 946
Swanand Avatar asked Nov 16 '10 13:11

Swanand


1 Answers

You can't. That's part of the point of unions.

If you need to be able to tell, you can use something called a tagged union. Some languages have built-in support for these, but in C, you have to do it yourself. The idea is to include a tag along with the union which you can use to tell which version it is. Like:

enum TestUnionTag {NUM_NAME, TOTAL};

struct {
    enum TestUnionTag tag;
    union {
        struct {
            unsigned int Num;
            unsigned char Name[5];
        } TestStruct;
        unsigned char Total[7];
    } value;
} TestUnion;

Then in your code, you make sure you always set the tag to say how the union is being used.

About the sizeof: the struct is 12 bytes because there are 4 bytes for the int (most modern compilers have a 4-byte int, the same as a long int), then three bytes of padding and five bytes for the chars (i don't know if the padding comes before or after the chars). The padding is there so that the struct is a whole number of words long, so that everything in memory stays aligned on word boundaries. Because the struct is 12 bytes long, the union has to be 12 bytes long to hold it; the union doesn't change size according to what's in it.

like image 162
Tom Anderson Avatar answered Oct 06 '22 01:10

Tom Anderson