Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof not showing the expected output

#include <stdint.h>
#include <stdio.h>

typedef union {
    uint64_t u[2];
    struct {
        uint64_t a:30;
        uint64_t b:30;
        uint64_t c:30;
        uint64_t d:30;
        uint64_t e:8;
    }x;
} mystruct;

int main()
{
    printf("Size %d\n", sizeof(mystruct));
}

I am trying to compile it on 64 bit machine. The expected output was 16 but I am getting 24. I know some alignment happened here but i am not sure why as the struct x is exactly 16 bytes. Can someone explain this. Thanks

like image 968
adikshit Avatar asked Jan 07 '13 19:01

adikshit


3 Answers

From the C Standard:

(C99, 6.7.2.1p10) "[...] If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined."

So in your implementation they don't overlap: a and b members are in one unit, c and d are in another one unit and e is in another one unit: 8 + 8 + 8 = 24.

like image 91
ouah Avatar answered Sep 21 '22 15:09

ouah


For a 64-bit machine, fields a and b use 60 bits of the first 64-bit value in the struct, c and d use 60 bits of the next 64-bit value in the struct, and then because e is 8 bits it can't fit into the 4 bits left over from that 64-bit value so another 64-bit value is needed. Thus 8x3 = 24 bytes.

like image 23
JohnnyHK Avatar answered Sep 20 '22 15:09

JohnnyHK


An element of a bit field will never overlap two memory "units" (in your case the memory unit is a 64bits element).

Beside the fact that bitfield implementation are compiler dependant, there is all chances that your bit-field structure is actually stored the following way in memory:

struct {
    uint64_t a:30;
    uint64_t b:30;
    uint64_t :4;
    uint64_t c:30;
    uint64_t d:30;
    uint64_t :4;
    uint64_t e:8;
    uint64_t :56;
}x;
like image 21
greydet Avatar answered Sep 19 '22 15:09

greydet