tags:

views:

185

answers:

7

Possible Duplicate:
Difference between a Structure and a Union in C

I could understand what a struct means. But, i am bit confused with the difference between union and struct. Union is like a share of memory. What exactly it means.?

+8  A: 

With a union, all members share the same memory. With a struct, they do not share memory, so a different space in memory is allocated to each member of the struct.

For example:

union foo
{
 int x;
 int y;
};

foo f;
f.x = 10;
printf("%d\n", f.y);

Here, we assign the value of 10 to foo::x. Then we output the value of foo::y, which is also 10 since x and y share the same memory. Note that since all members of a union share the same memory, the compiler must allocate enough memory to fit the largest member of the union. So a union containing a char and a long would need enough space to fit the long.

But if we use a struct:

struct foo
{
 int x;
 int y;
};

foo f;
f.x = 10;
f.y = 20;
printf("%d %d\n", f.x, f.y);

We assign 10 to x and 20 to y, and then print them both out. We see that x is 10 and y is 20, because x and y do not share the same memory.

EDIT: Also take note of Gman's comment above. The example I provided with the union is for demonstration purposes only. In practice, you shouldn't write to one data member of a union, and then access another data member. Usually this will simply cause the compiler to interpret the bit pattern as another type, but you may get unexpected results since doing this is undefined behavior.

Charles Salvia
Thanks for the answer Charles. But, i would like to know which memory they going to share or how much memory is allocated for union..?
Vinaychalluru
Thank u Charles. Now i got it. So, by using two different data types in union, we are allocating the memory to fit the largest member and share it with all other members.
Vinaychalluru
It's worth pointing out that the reason for unions is to represent something that is either of type A or of type B, but not both at once. It corresponds loosely to Sum types in ML, Haskell, etc.
wnoise
+2  A: 

Each member of a union shares the same memory. That means if you change one, you change the others. And if the members are of different types, this can have unpredictable results. (not exactly unpredictable, but hard to predict unless you are aware of the underlying bit patterns that make up the data members).

PigBen
Thank u "PigBen". Its good to know that when the data types are different, changes in members gets us some garbage results. :)
Vinaychalluru
+2  A: 

I suppose one way you can think of a union is that it is a set of aliases of varying type to a block of memory where each member of the union is an "alias" with a given type. Each alias refers to the same address in memory. How the bits at that address are interpreted are determined by the alias' type.

The amount of memory the union occupies is always equal to or possibly larger than the largest sized "member" of the union (due to alignment restrictions).

Jeff M
Thank u "Jeff M". U replied that the memory occupied is equal or possibly lareger due to alignment restrictions. What does this "Alignment restrictions" mean.?
Vinaychalluru
@Vinay: Refer to [this answer](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member/119128#119128). In summary, types are required to be stored at certain memory addresses. e.g., 32-bit ints are stored on addresses which are a multiple of 4, 16-bit shorts a multiple of 2, etc. So a struct will add _padding_ to accommodate this requirement. The same applies to unions as well.
Jeff M
@Jeff: Thank U. The answer is helpful and informative.
Vinaychalluru
A: 

I've used unions to convert bytes to and from other types. I find it easier than bit-shifting.

union intConverter {
    int intValue;
    struct {
        byte hi;
        byte lo;
    } byteValue;
}

intConverter cv;
cv.intValue =1100;
printf("%X %X\n", cv.byteValue.hi, cv.byteValue.lo);

Where int is 16-bit (was used on a micro controller).

Sam
Thanks to the answer Sam.
Vinaychalluru
This is a dangerous way to use them because there's no guarantee that your "hi" byte is actually the, you know, high byte.
JUST MY correct OPINION
true, you do need to know the endian of what its running on
Sam
+1  A: 

It may be more useful to have an uncontrived example of what this is good for. (I say "uncontrived" because most bit-banging uses of union are extremely treacherous. Bit-banging unions taken from big-endian to little-endian hardware break in the most (initially) mystifying ways.) (Of course, I've written bit-banging unions to tear apart floating point numbers to implement orders-of-magnitude-faster-than-the-library math functions. I just add assertions about which members are supposed to have the same addresses.)

    struct option1 { int type; /* other members */ };
    struct option2 { int type; /* other members */ };
    struct option3 { int type; /* other members */ };
    union combo {
      int type; // guaranteed to exactly overlap with the structs' ints type.
      struct option1;
      struct option2;
      struct option3;
    };
   // ...
   void foo(union combo *in) {
      switch(in.type) {
        case 1: { struct option1 *bar = in;  //then process an option1 type of request }
        case 2: { struct option2 *bar = in;  //then process an option2 type of request }
        case 3: { struct option3 *bar = in;  //then process an option3 type of request }
      }

This kind of construction is very common in X programming and other situations where one wishes to make a function that can receive many different types of messages (with different argument and layout requirements).

Eric Towers
Thanks for the answer Eric.
Vinaychalluru
It is illegal in C (and even C99) to have a declaration after a label, such as `case 1:`. Also, the identifier `option1` et. al are tags, so you need to declare with `struct option1 *bar`. You can introduce a new scope after each case label if you want to declare variables.
dreamlax
@dreamlax: Unsimplified code to decrease readability.
Eric Towers
A: 

Run this program and find out the output.

#include < stdio.h >

int main()
{
  union _testUnion
  {
    long long x;
    long long y;
  } testUnion;

  struct _testStruct
  {
    long long x;
    long long y;
  }testStruct;
  printf("Sizeof Union %d\n",sizeof(testUnion));
  printf("Sizeof Struct %d\n",sizeof(testStruct));
  return;
}

You will find that the size of struct is double than that of union. This is because union has allocated space for only one variable while struct has allocated for two.

Manoj R
Thank u Manoj. Ya, i understood the same thing u replied. Its good to know.
Vinaychalluru
A: 

Most answers here are correct. A union is essentially a way to access same data in different ways (For example, you can access/interpret 4 bytes of memory as 1 integers, or as 4 characters). Structs as you know are straightforward - a collection of different, seprate objects with their own memory.

Usually you require Unions at a much later stage in programming as compared to Structs.

JP19