2

I have defined 2 structures in C Language, both contains 2 ints and 1 char. When I print size of both of them, its giving results I can't justify. This is my code :

#include<stdio.h>
struct sample
{
    int a:6;
    int b:12;
    char s;
} st;
struct name
{
    int a:28;
    int b:12;
    char ch;
} st1;

int main()
{
    int i=sizeof(st);
    printf("st : %d\n\n",i);

    i=sizeof(st1);
    printf("st1 : %d\n\n",i);
}

output is :

st : 4
st1 : 8

How the size of st is 4 byte and st1 is 8 bytes?

I found this similar question but the values I am getting are still not justified. According to this question, my structure st should be taking 3 bytes and st1 should be taking 6 bytes.

Community
  • 1
  • 1
Sourabh
  • 1,757
  • 6
  • 21
  • 43

1 Answers1

5

A typical compiler will determine structure alignment requirements from the most strict alignment requirement among the struct members. Bit-fields are typically treated as ordinary fields in that process.

That means since your first structure contains a member of type int (which, apparently, has alignment requirement of 4), the entire structure will have the alignment requirement of 4 and its size will always be divisible by 4. 4 is the minimum size it can possibly have. Since you used only 18 bits for the bit-fields (3 bytes at least), the compiler managed to pack everything into 4 bytes. But it can't make it smaller than 4.

(Note, BTW, that just by counting the bits required gives us the total of 26. How on Earth you expected this to fit into 3 bytes, even ignoring any alignment considerations, is not clear to me.)

In your second structure you used 40 bits for the bit-fields (which involves 5 bytes already). Now the compiler is unable to pack everything into 4 bytes, so it uses 8 bytes. Again, the struct size is required to be divisible by 4, meaning that if 4 is not enough, then next smallest size is 8.

If you want to override that alignment behavior, you have to use your compiler-specific features to force the 1-byte alignment to all data types (#pragma pack etc.). That way you might be able to reduce the size of your second struct. But what you observe now is perfectly expected under the default alignment settings.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Can't upvote your post because I've already ended up with my 40 votes for today. Anyways,it's really a beautiful explanation,much better than mine! – Am_I_Helpful Aug 15 '14 at 17:35
  • 1
    An `int` might typically require 4-byte alignment, but there's no particular reason why an `int` *bit field* should require 4-byte alignment. But man ABIs do impose alignment requirements for bit fields, going beyond what the C standard requires. – Keith Thompson Aug 15 '14 at 17:35
  • @Keith Thompson: That is true. However in practice I often observe that compilers treat bit-fields as "first class citizens" in that regard. Even if the bit-field itself requires no alignment, the *allocation unit* that provides space for that bit-field is assumed to have the declared type with corresponding alignment requirements. – AnT stands with Russia Aug 15 '14 at 17:38
  • "most strict alignment requirement among the struct members" is spot on, +1 earlier for that. But it may leave the impression that "alignment requirement" == `sizeof()`. Thought your may want to expand on that. – chux - Reinstate Monica Aug 15 '14 at 19:44