2

Given there are some unrelated flags (sta_scan, search) that are defined as bitfields in a struct like below. Does the location where those flags are declared matter (in terms of memory save)?

struct sta_all {
    char name[16];
    unsigned int sta_scan:1;
    ...
    int interval;
    unsigned int search:1;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
artm
  • 17,291
  • 6
  • 38
  • 54
  • 2
    Each of those bit-fields will probably be allocated as much space as the base type (`unsigned int`) and will use 1 of the 32 (16, 64, …) bits in that storage unit. If you decide to use bit-fields, you should make sure all the bit-fields are clustered together; it will minimize the space wasted. You should think about whether `bool` (from ``, or `_Bool`) will serve your purposes as well, or better. Lots of details about bit-fields are implementation defined, but in the context of a structure, the compiler has no freedom to move the bitfields around. – Jonathan Leffler Sep 01 '16 at 03:00
  • compilers are not allowed to [reorder struct members](http://stackoverflow.com/q/9486364/995714) so you need to do that yourself, unless you enable some [compiler options](http://stackoverflow.com/q/14671253/995714) – phuclv Sep 01 '16 at 03:08
  • artM nice question, I make an edit to my answer, since last night, instead of counting sheep in my bed, I was counting bits, hope you will find it helpful! :) – gsamaras Sep 01 '16 at 16:00
  • @gsamaras cool. The original struct is actually a lot bigger, and indeed I saw many unrelated flags like these are spread all over. So I was wondering whether this scattered bitfields would really make a difference, or we may just use normal int instead. – artm Sep 01 '16 at 21:58

2 Answers2

3

Yes, but not always.


Check this example:

#include <stdio.h>
#include <string.h>

struct {
    char name[16];
    unsigned int sta_scan:1;
    int interval;
    unsigned int search:1;
} sta_all;

int main( ) {

   sta_all.interval = 4;
   printf( "Sizeof(sta_all) : %zu\n", sizeof(sta_all) );

   return 0;
}

Output:

Sizeof(sta_all) : 28

and:

#include <stdio.h>
#include <string.h>

struct {
    char name[16];
    unsigned int sta_scan:1;
    unsigned int search:1;
    int interval;
} sta_all;

int main( ) {

   sta_all.interval = 4;
   printf( "Sizeof(sta_all) : %zu\n", sizeof(sta_all) );

   return 0;
}

Output:

Sizeof(sta_all) : 24

This happens because of padding, on my platform.

By the way, if you are really desperate for memory efficiency, and you can accept losing in access speed, then you can use packing, as the link above explains.

Note: The example above confirms what Jonathan Leffler mentioned in this comment:

Each of those bit-fields will probably be allocated as much space as the base type (unsigned int) and will use 1 of the 32 (16, 64, …) bits in that storage unit. If you decide to use bit-fields, you should make sure all the bit-fields are clustered together; it will minimize the space wasted. [...]. In the context of a structure, the compiler has no freedom to move the bitfields around.

..which comes to perfect harmony with the linked answer, since the compiler will have to add less char gap_{i}[3];, when we cluster the bitfields, thus minimizing the size of the struc!


Is it worth it?

Not that much IMHO... :)

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
1

In general, yes. Struct elements will normally be aligned in some way (usually to the size of the element, occasionally something larger), and mixing various sizes can result in a lot of padding. There are ways to mitigate this. In general, if you group all elements of the same size together, they'll probably get packed without any padding. It is possible to use pragmas to force a struct to be packed with no padding, but then this will result in inefficient unaliged accesses to struct members.

alex.forencich
  • 1,355
  • 11
  • 16