C- The size of the structure when the bit field is used and how it is stored in memory

void main() { struct bitfield { signed int a :3; unsigned int b :13; unsigned int c :1; }; struct bitfield bit1 = { 2, 14, 1 }; clrscr(); printf("%d", sizeof(bit1)); getch(); } 

Why is the size 4 bytes here? And how exactly are these elements stored in memory?

+4
source share
3 answers

Almost every aspect of bit fields is implementation-defined. Even the subscription of the "plain int " int is determined by the implementation; it may be signed or unsigned. The layout of the fields β€” regardless of whether they go from the most significant bit to the least significant bit in the containing β€œunit” (the term used in the standard) or from the least significant β€” is the implementation. The size of the largest allowable bit field; when bit-bit is stored in a new block; all of this is determined by implementation.

For example, on Mac OS X 10.8.4 using GCC 4.8.1, you can demonstrate that the struct bitfield in the question is stated with a occupying the 3 least significant bits (bit 0-2), b occupying the next 13 bits (3-15) and c , occupying the following 1 bit (16):

 #include <stdio.h> static void print_info(int v); int main(void) { int values[] = { 0x55555555, 0xAAAAAAAA, 0x87654321, 0xFEDCBA98, 0xFEDCBA90, 0xFEDCBA91, 0xFEDCBA92, 0xFEDCBA93, 0xFEDCBA94, 0xFEDCBA95, 0xFEDCBA96, 0xFEDCBA97, 0xFEDCBA98, 0xFEDCBAA0, 0xFEDCBAA8, 0x0000BAA0, 0x0001BAA0, 0x00000008, 0x00000010, 0x00000018, 0x0000FFF0, 0x0000FFF8, }; for (size_t i = 0; i < sizeof(values)/sizeof(values[0]); i++) print_info(values[i]); return 0; } static void print_info(int v) { union { unsigned int x; struct bitfield { signed int a:3; unsigned int b:13; unsigned int c:1; } y; } u; ux = v; printf("0x%.8X => %2d 0x%.4X %1X\n", ux, uya, uyb, uyc); } 

Output Example:

 0x55555555 => -3 0x0AAA 1 0xAAAAAAAA => 2 0x1555 0 0x87654321 => 1 0x0864 1 0xFEDCBA98 => 0 0x1753 0 0xFEDCBA90 => 0 0x1752 0 0xFEDCBA91 => 1 0x1752 0 0xFEDCBA92 => 2 0x1752 0 0xFEDCBA93 => 3 0x1752 0 0xFEDCBA94 => -4 0x1752 0 0xFEDCBA95 => -3 0x1752 0 0xFEDCBA96 => -2 0x1752 0 0xFEDCBA97 => -1 0x1752 0 0xFEDCBA98 => 0 0x1753 0 0xFEDCBAA0 => 0 0x1754 0 0xFEDCBAA8 => 0 0x1755 0 0x0000BAA0 => 0 0x1754 0 0x0001BAA0 => 0 0x1754 1 0x00000008 => 0 0x0001 0 0x00000010 => 0 0x0002 0 0x00000018 => 0 0x0003 0 0x0000FFF0 => 0 0x1FFE 0 0x0000FFF8 => 0 0x1FFF 0 

Test values ​​are not completely randomly selected. From the test values ​​0xFEDCBA90 to 0xFECBA97, we see that the least significant 3 bits contain a . From the test values ​​0x0000BAA0 and 0x0001BAA0, we see that the 17th bit (or bit 16) contains c . And from the test values ​​from 0x00000008 to 0x0000FFF8, we see that bits 3-15 contain b .

However, it should be noted that the code is controversial and portable in theory; since the code is written in ux and then reads ux and uya , uyb and uyc , it does not refer to the last union member strictly adhering to undefined. In practice, this "always" works (I have not heard about a system where it does not work - it is unlikely, but it is technically impossible for a system to exist in which it does not work).

This layout is not the only possible layout for any part of the imagination. However, I do not have access to compilers or systems that demonstrate alternative layouts.


In ISO / IEC 9899: 2011, section Β§6.7.2.1, the Structure and Union Specification says:

ΒΆ11 An implementation can allocate any storage address block large enough to hold a bit field. If there is enough space left, a bit field that immediately follows another bit field in the structure should be packed into adjacent bits of the same block. If there is not enough space, then whether a bit field that does not fit will fit in the next block or overlap adjacent units is determined by the implementation. The order of distribution of bit fields within a unit (from high order to low or low order) is determined by the implementation. The alignment of the storage address block is not indicated.

ΒΆ12 Declaring a bit field without a declarator, but only a colon and a width, indicates an unnamed bit field. 126) As a special case, an element of the structure of a bit field with a width of 0 indicates that the additional bit field should not be packed in the block in which the previous bit field was placed, if any.

126) The structure element of an unnamed bit field is useful for filling to match external overlays.

A small version of the structure in question:

 struct exegesis { signed int a:3; unsigned int :0; unsigned int b:13; unsigned int :0; unsigned int c:1; }; 

This structure has a size of 12 (on the same compiler / platform as before). The storage block for bit fields on this platform is 4 bytes, so anonymous zero-width fields start a new memory block. a is stored in the least significant 3 bits of the first 4-byte block; b in the least significant 13 bits of the second 4-byte block; and c in the lowest bit value of the third 4-byte block. As noted in the quote from the standard, you can have anonymous bit fields that are greater than 0.

+6
source

How a bit field is stored in memory depends on the implementation.

One possible reason is that a bit field that has 17 bits must contain at least 3 bytes, but the compiler selects it for 4 bytes.

Again, almost everything about the bit field is implementation dependent, including their size and memory layout.

Finally, do not use void main , always stay with int main

+3
source

how the bitfield is stored depends on the architecture, for the small end from left to right and for the large right corner to the right. memory in memory occurs with the word size.1 byte - 1 word.so in our example its 17 bits, since the first two 8 bits will be stored in the first two words. The next bit will be stored in the next word. the size should be 3 bytes, but the compiler does some padding, so finally the size becomes 4 bytes.

for storage in memory you can refer to this link http://en.wikipedia.org/wiki/Endianness

0
source

Source: https://habr.com/ru/post/1497534/


All Articles