简体   繁体   中英

value of members of unions with bit-fields

I'm trying to learn how memory is allocated for unions containing bit-fields.

I've looked at posts and questions similar to this and have understood that padding is involved most of the times depending on the order in which members are declared in structure.

1.

union Example
{ int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
}

Output: -1

2.

union Example
{ unsigned int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
}

Output: 3

Can someone please explain the output? Is it just the standard output for such cases? I use the built-in gcc compiler in ubuntu

The way your compiler allocates bits for bit-fields in a union happens to overlap the low bits of j with the bits of i . Thus, when j is set to 15, the two bits of i are each set to 1.

When i is a two-bit signed integer, declared with int i:2 , your compiler interprets it as a two-bit two's complement number. With this interpretation, the bits 11 represent −1.

When i is a two-bit unsigned integer, declared with unsigned int i:2 , it is pure binary, with no sign bit. With this interpretation, the bits 11 represent 3.

The program below shows that setting a signed two-bit integer to −1 or an unsigned two-bit integer to 3 produce the same bit pattern in the union, at least in your C implementation.

#include <stdio.h>


int main(void)
{
    union Example
    {
        unsigned u;
        int i : 2;
        int j : 9;
        unsigned int k : 2;
    } ex;

    ex.u = 0;
    ex.i = -1;
    printf("ex.i = -1:  %#x.\n", ex.u);

    ex.u = 0;
    ex.j = 15;
    printf("ex.j = 15:  %#x.\n", ex.u);

    ex.u = 0;
    ex.k = 3;
    printf("ex.k =  3:  %#x.\n", ex.u);
}

Output:

ex.i = -1:  0x3.
ex.j = 15:  0xf.
ex.k =  3:  0x3.

Note that a compiler could also allocate the bits high-to-low instead of low-to-high, in which case the high bits of j would overlap with i , instead of the low bits. Also, a compiler could use different sizes of storage units for the nine-bit j than it does for the two-bit i , in which case their bits might not overlap at all. (For example, it might use a single eight-bit byte for i but use a 32-bit word for j . The eight-bit byte would overlap some part of the 32-bit word, but not necessarily the part used for j .)

Example1

#include <stdio.h>

union Example
{ int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);
   printf("\nSize of Union : %lu\n" , sizeof(ex));

   return 0;
}

Output:

-1
Size of Union : 4

Observations:

From this ouput, We can deduce that even if we use 9 bits( max ), Compiler allocates 4 byte(because of padding). Statement union Example ex; allocates 4 bytes of memory for Union Example object ex. Statement ex.j=15; asigns 0x0000000F to that 4 Byte of memory. So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits. Statement printf("%d",ex.i); tries to print ex.i( which is 2 bits). We have 1-1 from the previous statement.

Here comes the interesting part, ex.i is of type signed int. Hence first bit is used to assign signed representation and most cpu does signed representation in 2's complement form. So if we does reverse 2's complement of 1-1 we will get value 1. So the ouput we get is -1.

Example2

#include <stdio.h>

union Example
{ unsigned int i:2;
  int j:9; 
};


int main(void)
{ 
   union Example ex;
   ex.j=15;
   printf("%d",ex.i);


   return 0;
}

Output:

3

Observations:

Statement union Example ex; allocates 4 bytes of memory for Union Example object ex. Statement ex.j=15; asigns 0x0000000F to that 4 Byte of memory. So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits. statement printf("%d",ex.i); tries to print ex.i( which is 2 bits). We have 1-1 from the previous statement.

Same as Above example but here ex.i is of type unsigned int. Hence no signed bit is used here for representation. So whatever is stored in the 2 bit location is the exact value. Hence the ouput is 3.

Hope i cleared your doubt. Please check for 2's and 1's complement in the internet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM