-1

In my program below I can understand why the short members of the union are stored in the same 2 bytes (as size of the union is that of the largest member).But I just don't get it why all 4 character members are stored in the same byte while one would assume they would be spread across two bytes and stored like

c1,c3--->first byte
c2,c4--->2nd byte

Or more clearly

Byte1     Byte2
----short a----
----short b----
--c1--    --c2--
--c3--    --c4--

What is the reason they are stored instead as

Byte1     Byte2
----short a----
----short b----
--c1-- 
--c2--
--c3--    
--c4--

What is the reason behind this?Her's the program:

#include<stdio.h>

int main(void)
{
    union test
    {
        short a,b;
        char c1,c2,c3,c4;
    } var= {65};
    printf("%hd,%hd,%c,%c,%c,%c",var.a,var.b,var.c1,var.c2,var.c3,var.c4);
}

Result:

   65,65,A,A,A,A
timrau
  • 22,578
  • 4
  • 51
  • 64
Thokchom
  • 1,602
  • 3
  • 17
  • 32
  • Because that's not how unions work. Use a `char[4]` instead – Dave May 17 '13 at 21:19
  • 3
    "I just don't get it why all 4 character members are stored in the same byte" -- um, because that's what "union" means -- store each member in the same place. "as size of the union is that of the largest member" -- of course, because it can't be any less. "while one would assume they would be spread across two bytes" -- I can't imagine why one would assume such a thing. – Jim Balter May 17 '13 at 21:22
  • This isn't a bad question; it just demonstrates the author didn't know this about C. +1 to counteract. – geometrian Jul 02 '13 at 08:32

4 Answers4

3

Because the union doesn't work that way.

If you want it to work like this, you should mix anonymous structs and unions like:

union test
{
    short a,b;
    struct { char c1,c2; };
    struct { char c3,c4; };
};

EDIT:

It looks like anonymous structs are non-standard. If you want standards-conforming code, you have to use plain structs, and deal with longer syntax.

union test
{
    short a,b;
    struct c { char _1,_2; };
    struct d { char _3,_4; };
};

test var;
if(var.c._1 == var.d._3) {}
Community
  • 1
  • 1
milleniumbug
  • 15,379
  • 3
  • 47
  • 71
2

one would assume they would be spread across two bytes

Why would anybody assume it? It's certainly wrong. All members of the union are required to start at the same memory location.

C11 standard, section 6.7.2.1.6:

  1. As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, and a union is a type consisting of a sequence of members whose storage overlap.

section 6.7.2.1.16:

  1. The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit- field, then to the unit in which it resides), and vice versa.
0

Because that's precisely what unions do: All members will take up the same address and the size of the union will be equal to the size of the variable with the greatest size. (That sounded weird)

For example:

union group {
    double d;
    char c;
} u;

The size of that union will be the size of the double because all the members will start at the same location in memory and a double is guaranteed to have a size greater than that of a char.

Edit: One good argument for implementing this is to save memory. C was invented back in the 70's when memory was pretty scarce, so at the time, you would've been making a difference by combining two variables in a union in cases where you only require the data in one but not both.

user123
  • 8,970
  • 2
  • 31
  • 52
0

Unions in C are only ever as large as their largest contained type. Each of their types is overlaid on the same memory space.

The code you presented creates a union of size short which has two short references and four char references.

zellio
  • 31,308
  • 1
  • 42
  • 61