failing to achieve desired size of a BitField structure

Discussion in 'C++' started by nass, Feb 13, 2007.

  1. nass

    nass Guest

    hello everyone,
    i read somewhere that it is possible to define a BitFields structure
    so i set out to:

    Code:
    struct IC_X
    {
    	unsigned short int dump:2;
    	unsigned short int ic1:10;
    	unsigned short int ic2:10;
    	unsigned short int ic3:10;
    };
    struct EVS
    {
    	unsigned short int dump:2;
    	unsigned short int v:10;
    	unsigned short int p:10;
    	unsigned short int q:10;
    };
    struct SE_P
    {
    	unsigned short int dump:1;
    	unsigned short int c1s:1;
    	unsigned short int c2s:1;
    	unsigned short int c3s:1;
    	unsigned short int c1e:1;
    	unsigned short int c2e:1;
    	unsigned short int c3e:1;
    	unsigned short int rC:1;
    };
    struct ALS
    {
    	unsigned short int dump:5;
    	unsigned short int al1:1;
    	unsigned short int al3:1;
    	unsigned short int al4:1;
    };
    then
    Code:
    struct LogEntry
    {
    	IC_X icx;
    	EVS evs;
    	SE_P sep;
    	ALS als;
    	FileTime TimeStamp;
    };
    FileTime is just a typedef for an unsigned long.
    dump fields are NOT used.

    so basically i wanted to pack 3, 10-bit numbers in IC_X (and leave the
    2 MSB bits unused), then another 3 10-bit nums in EVS, then 7 bools in
    SE_P, and another 3 bools in ALS.
    finally pack them all together (along with an unsigned long
    timeStamp) to a 14byte long structure.
    with this structure though i get a sizeof(LogEntry)=20 in execution...

    what am i missing?
    thank you for your help
    nass
     
    nass, Feb 13, 2007
    #1
    1. Advertising

  2. nass

    dasjotre Guest

    On 13 Feb, 10:43, "nass" <> wrote:
    <snip>

    You work on a 32 bit machine.

    It is all due to alignment of primitive types.
    In IC_X, the firs two members fit in one short,
    next two can only fit in two shorts, and since
    short alignment is 2, sizeof(IC_X) == 6.

    EVS is the same.

    SEP members fit in one short, hence
    sizeof(SEP) == 2. same with ALS.

    FileTime is long which is aligned on
    word boundary hence sizeof(FileTime) = 4

    It all adds up to 20.

    make IC_X and EVS to use unsigned
    int instead of short and SEP and ALS
    to use char and then look-up struct alignment
    directive for your compiler and set it to 1
    (remember to reset it afterwards)
     
    dasjotre, Feb 13, 2007
    #2
    1. Advertising

  3. nass

    nass Guest

    thank you for the reply. in the end actually re-did the structure in
    the following way:

    struct LogEntry
    {
    unsigned ic1:10;
    unsigned ic2:10;
    unsigned ic3:10;
    unsigned dm1:2;

    unsigned v:10;
    unsigned p:10;
    unsigned q:10;
    unsigned dm2:2;

    unsigned c1s:1;
    unsigned c2s:1;
    unsigned c3s:1;
    unsigned c1e:1;
    unsigned c2e:1;
    unsigned c3e:1;
    unsigned rC:1;
    unsigned dm3:1;

    unsigned al1:1;
    unsigned al3:1;
    unsigned al4:1;
    unsigned dm4:5;

    unsigned long TimeStamp;
    } __attribute__ ((__packed__));

    now sizeof(logEntry) returns 14 as expected. the 'dm*' are dummy
    unused variables.
    Thank you for your help
    nass
     
    nass, Feb 13, 2007
    #3
  4. nass

    Pete Becker Guest

    nass wrote:
    > thank you for the reply. in the end actually re-did the structure in
    > the following way:
    >
    > struct LogEntry
    > {
    > unsigned ic1:10;
    > unsigned ic2:10;
    > unsigned ic3:10;
    > unsigned dm1:2;
    >
    > unsigned v:10;
    > unsigned p:10;
    > unsigned q:10;
    > unsigned dm2:2;
    >
    > unsigned c1s:1;
    > unsigned c2s:1;
    > unsigned c3s:1;
    > unsigned c1e:1;
    > unsigned c2e:1;
    > unsigned c3e:1;
    > unsigned rC:1;
    > unsigned dm3:1;
    >
    > unsigned al1:1;
    > unsigned al3:1;
    > unsigned al4:1;
    > unsigned dm4:5;
    >
    > unsigned long TimeStamp;
    > } __attribute__ ((__packed__));
    >
    > now sizeof(logEntry) returns 14 as expected. the 'dm*' are dummy
    > unused variables.
    >


    A more portable way of doing that is to specify a width of 0, which
    tells the compiler to advance to the next allocation unit boundary.
    Also, you don't need to give names to the ones that are used only for
    padding. Of course, none of the details are guaranteed: you have to
    adapt to the compiler you're using.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Feb 13, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. zb32

    bitfield optimizations

    zb32, Jul 13, 2004, in forum: C++
    Replies:
    1
    Views:
    1,101
    David Harmon
    Jul 13, 2004
  2. Claudio

    bitfield & union strange ?!

    Claudio, Aug 1, 2004, in forum: C++
    Replies:
    2
    Views:
    4,954
    Gottfried Eibner
    Aug 2, 2004
  3. Replies:
    0
    Views:
    541
  4. Davide Bruzzone
    Replies:
    9
    Views:
    396
    Adam S. Roan
    Aug 27, 2003
  5. Andy Venikov

    bitfield size check

    Andy Venikov, Jun 22, 2004, in forum: C Programming
    Replies:
    3
    Views:
    790
Loading...

Share This Page