C – Inaccurate size of a struct with bit fields on my book

  • A+
Category:Languages

I'm studying the basics of C language, I arrived at the chapter of structures with bit fields, the book shows me an example of struct with two different types of data, various bool and various unsigned int. In the following comment 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 brings in an 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:

C - Inaccurate size of a struct with bit fields on my book

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

C - Inaccurate size of a struct with bit fields on my book


To my surprise there seems to be a difference between some GCC 4.9.2 online compilers. First, this is my code:

#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; };  struct test_packed {        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; } __attribute__((packed));  int main(void) {        struct test padding;        struct test_packed no_padding;         printf("with padding: %zu bytes = %zu bits/n", sizeof(padding), sizeof(padding) * 8);        printf("without padding: %zu bytes = %zu bits/n", sizeof(no_padding), sizeof(no_padding) * 8);         return 0; } 

And now, results from different compilers.

GCC 4.9.2 from WandBox:

with padding: 4 bytes = 32 bits without padding: 2 bytes = 16 bits 

GCC 4.9.2 from http://cpp.sh/:

with padding: 4 bytes = 32 bits without padding: 2 bytes = 16 bits 

BUT

GCC 4.9.2 from theonlinecompiler.com:

with padding: 16 bytes = 128 bits without padding: 16 bytes = 128 bits 

(to properly compile you need to chagne %zu to %u)

EDIT

@interjay's answer might explain this. When I added -mms-bitfields to GCC 4.9.2 from WandBox, I got this:

with padding: 16 bytes = 128 bits without padding: 16 bytes = 128 bits 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: