Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inaccurate size of a struct with bit fields in my book

Tags:

I'm studying the basics of the C language. I arrived at the chapter of structures with bit fields. The book shows an example of a struct with two different types of data: various bools and various unsigned ints.

The book declares that the structure has a size of 16 bits and that without using padding the structure would measure 10 bits.

This is the structure that the book uses in the example:

#include <stdio.h> #include <stdbool.h>  struct test{         bool opaque                 : 1;        unsigned int fill_color     : 3;        unsigned int                : 4;        bool show_border            : 1;        unsigned int border_color   : 3;        unsigned int border_style   : 2;        unsigned int                : 2; };  int main(void) {        struct test Test;         printf("%zu\n", sizeof(Test));         return 0; } 

Why on my compiler instead does the exact same structure measure 16 bytes (rather than bits) with padding and 16 bytes without padding?

I'm using

GCC (tdm-1) 4.9.2 compiler; Code::Blocks as IDE. Windows 7 64 Bit Intel CPU 64 bit 

This is result I'm getting:

enter image description here

Here is a picture of the page where the example is:

enter image description here

like image 815
AlexQualcosa Avatar asked Apr 26 '18 10:04

AlexQualcosa


People also ask

How do you calculate the size of a bit field?

In above student structure size of the structure without bit field is size of (StdId) + size of (Age) = 8 bytes + 8 Bytes = 16 bytes. After using bit fields to its members, it is 8 bits + 4 bits = 12 bits = 1.5 bytes which is very much less. Hence we can save lot of memory.

What is a bit field Why are bit fields used with structures?

These space-saving structure members are called bit fields, and their width in bits can be explicitly declared. Bit fields are used in programs that must force a data structure to correspond to a fixed hardware representation and are unlikely to be portable.

How are bit fields stored in memory?

Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.

Can bit fields only be declared as part of a structure?

Bit fields can only be declared as part of a structure. The address-of operator (&) cannot be applied to bit-field components.


1 Answers

The Microsoft ABI lays out bitfields in a different way than GCC normally does it on other platforms. You can choose to use the Microsoft-compatible layout with the -mms-bitfields option, or disable it with -mno-ms-bitfields. It's likely that your GCC version uses -mms-bitfields by default.

According to the documentation, When -mms-bitfields is enabled:

  • Every data object has an alignment requirement. The alignment requirement for all data except structures, unions, and arrays is either the size of the object or the current packing size (specified with either the aligned attribute or the pack pragma), whichever is less. For structures, unions, and arrays, the alignment requirement is the largest alignment requirement of its members. Every object is allocated an offset so that: offset % alignment_requirement == 0
  • Adjacent bit-fields are packed into the same 1-, 2-, or 4-byte allocation unit if the integral types are the same size and if the next bit-field fits into the current allocation unit without crossing the boundary imposed by the common alignment requirements of the bit-fields.

Since bool and unsigned int have different sizes, they are packed and aligned separately, which increases the struct size substantially. The alignment of unsigned int is 4 bytes, and having to realign three times in the middle of the struct leads to a 16 byte total size.

You can get the same behavior of the book by changing bool to unsigned int, or by specifying -mno-ms-bitfields (though this will mean you can't inter-operate with code compiled on Microsoft compilers).

Note that the C standard does not specify how bitfields are laid out. So what your book says may be true for some platforms but not for all of them.

like image 104
interjay Avatar answered Sep 29 '22 20:09

interjay