Bit-fields and packing/alignment

Discussion in 'C++' started by =?iso-8859-1?q?Lars_Rune_N=F8stdal?=, Jul 26, 2004.

  1. struct X {
    unsigned int a : 1;
    unsigned int b : 1;
    };

    int main()
    {
    X* x = new X;
    x->a = 1;
    x->b = 1;
    return(0);
    }


    Will this code not result in the two bits 'a' and 'b', both with the value
    1, following each other (packed/aligned) in memory?

    Like this, where the content between [ and ] represents a single bit in
    memory: ..[1][1]..

    From TC++PL. (§C8.1): "..using (bit)fields to pack several variables into
    a byte.."

    I assume a byte (or allocation unit, or word) on any platform known to man
    has room for at least two bits, and therefore will not straddle.

    From http://www.parashift.com/c -faq-lite/intrinsic-types.html: "The C++
    language guarantees a byte must always have at least 8 bits."

    From the C++ standard (2003) (§9.6): "Bit fields are packed into some
    addressable allocation unit."

    Note that I'm not taking into account the details about stuff like MSB or
    the actual size of what's allocated and possibly padded, or ignored as a
    value here. What I want to know is if it's guaranteed that 'a' and 'b' is
    packed/aligned here.

    This is the output of the GDB under Linux (x86) when examining the
    contents of 'x':


    14 x->a = 1;
    (gdb) x x
    0x804a050: 00000000000000000000000000000000
    (gdb) step
    15 x->b = 1;
    (gdb) x x
    0x804a050: 00000000000000000000000000000001
    (gdb) step
    16 return(0);
    (gdb) x x
    0x804a050: 00000000000000000000000000000011
    (gdb)

    Sorry if the question is wierd -- but we're having quite a discussion
    about this and I need to be 100% sure about how this works (and doesn't
    work).

    --
    Lars Rune Nøstdal
    http://lars.cpp.no/
     
    =?iso-8859-1?q?Lars_Rune_N=F8stdal?=, Jul 26, 2004
    #1
    1. Advertising

  2. "Lars Rune Nøstdal" <> schrieb im Newsbeitrag
    news:p...
    > struct X {
    > unsigned int a : 1;
    > unsigned int b : 1;
    > };
    >
    > int main()
    > {
    > X* x = new X;
    > x->a = 1;
    > x->b = 1;
    > return(0);
    > }
    >
    >
    > Will this code not result in the two bits 'a' and 'b', both with the

    value
    > 1, following each other (packed/aligned) in memory?


    STOP. You defined x.a and x.b as 'int'. and 'int' means: the buswidth
    of your processor. On a 32 bit processor, this will be 32 bits.

    > Like this, where the content between [ and ] represents a single bit

    in
    > memory: ..[1][1]..


    Either you got something really wrong here, or I don't know what you
    want to say...

    > From TC++PL. (§C8.1): "..using (bit)fields to pack several variables

    into
    > a byte.."


    Yes.

    unsigned char a_byte;

    a_byte = 0; // 00000000

    a_byte |= 5; // 00000101
    a_byte |= 2; // 00000111


    >
    > I assume a byte (or allocation unit, or word) on any platform known

    to man
    > has room for at least two bits, and therefore will not straddle.


    Ouch! A BYTE is defined as 8 BIT, a WORD as 2 BYTE (thus 16 BIT).
    Both are graeter than 2 BITS, thus, yes you can store 2 bits:


    >
    > From http://www.parashift.com/c -faq-lite/intrinsic-types.html:

    "The C++
    > language guarantees a byte must always have at least 8 bits."


    True.

    > From the C++ standard (2003) (§9.6): "Bit fields are packed into

    some
    > addressable allocation unit."


    True

    > Note that I'm not taking into account the details about stuff like

    MSB or
    > the actual size of what's allocated and possibly padded, or ignored

    as a
    > value here. What I want to know is if it's guaranteed that 'a' and

    'b' is
    > packed/aligned here.


    Yes, it's guaranteed. x.a (32 bits!?) then following x.b (32 bits)

    > This is the output of the GDB under Linux (x86) when examining the
    > contents of 'x':
    >
    >
    > 14 x->a = 1;
    > (gdb) x x
    > 0x804a050: 00000000000000000000000000000000
    > (gdb) step
    > 15 x->b = 1;
    > (gdb) x x
    > 0x804a050: 00000000000000000000000000000001
    > (gdb) step
    > 16 return(0);
    > (gdb) x x
    > 0x804a050: 00000000000000000000000000000011
    > (gdb)


    I don't know about gdb, but it seems weired...


    > Sorry if the question is wierd -- but we're having quite a

    discussion
    > about this and I need to be 100% sure about how this works (and

    doesn't
    > work).
    >
    > --
    > Lars Rune Nøstdal
    > http://lars.cpp.no/
    >
     
    Gernot Frisch, Jul 26, 2004
    #2
    1. Advertising

  3. Lars Rune Nøstdal wrote in
    news:p in comp.lang.c++:

    > struct X {
    > unsigned int a : 1;
    > unsigned int b : 1;
    > };
    >
    > int main()
    > {
    > X* x = new X;
    > x->a = 1;
    > x->b = 1;
    > return(0);
    > }
    >
    >
    > Will this code not result in the two bits 'a' and 'b', both with the
    > value 1, following each other (packed/aligned) in memory?
    >


    The Standard say's such things are implementation defined.

    > Like this, where the content between [ and ] represents a single bit
    > in memory: ..[1][1]..


    Most machines don't have *bit* addressable memory, so the consept of
    one bit following another in memory is fundamentaly flawed.

    >
    > From TC++PL. (§C8.1): "..using (bit)fields to pack several variables
    > into a byte.."
    >
    > I assume a byte (or allocation unit, or word) on any platform known to
    > man has room for at least two bits, and therefore will not straddle.


    Its a resanable assupmtion, in C++ a "byte" (aka char) has at least
    8 bits of object/value representation, however "reason" (aka logic)
    doesn't apply here, the Standard says that how bit-fields are allocated
    is implementation defined. If you *need* to know, you have to read the
    documentation for the compiler your using.

    >
    > From http://www.parashift.com/c -faq-lite/intrinsic-types.html: "The
    > C++ language guarantees a byte must always have at least 8 bits."
    >
    > From the C++ standard (2003) (§9.6): "Bit fields are packed into some
    > addressable allocation unit."
    >
    > Note that I'm not taking into account the details about stuff like MSB
    > or the actual size of what's allocated and possibly padded, or ignored
    > as a value here. What I want to know is if it's guaranteed that 'a'
    > and 'b' is packed/aligned here.


    No. But it may be (and probably is) guaranteed by you implementation
    (aka compiler), read you docs'.

    [snip]

    >
    > Sorry if the question is wierd -- but we're having quite a discussion
    > about this and I need to be 100% sure about how this works (and
    > doesn't work).
    >


    If you need your "bits" to be stored in specific bits of a larger
    object, you should store them in the larger object, and use the
    <<, >>, & and | operators to manipulate the value bits of this object.

    The only reasonable use of bitfields in portable code is to save
    some memory when you know the value of a field is storeable in
    a specific number of bits.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Jul 26, 2004
    #3
  4. =?iso-8859-1?q?Lars_Rune_N=F8stdal?=

    Jack Klein Guest

    On Mon, 26 Jul 2004 10:47:06 +0200, "Gernot Frisch" <>
    wrote in comp.lang.c++:

    >
    > "Lars Rune Nøstdal" <> schrieb im Newsbeitrag
    > news:p...
    > > struct X {
    > > unsigned int a : 1;
    > > unsigned int b : 1;
    > > };
    > >
    > > int main()
    > > {
    > > X* x = new X;
    > > x->a = 1;
    > > x->b = 1;
    > > return(0);
    > > }
    > >
    > >
    > > Will this code not result in the two bits 'a' and 'b', both with the

    > value
    > > 1, following each other (packed/aligned) in memory?

    >
    > STOP. You defined x.a and x.b as 'int'. and 'int' means: the buswidth
    > of your processor. On a 32 bit processor, this will be 32 bits.


    Do you have any idea at all what bit-fields are in C and C++?
    Apparently not. x.a and x.b will indeed each contain 1 bit.

    > > Like this, where the content between [ and ] represents a single bit

    > in
    > > memory: ..[1][1]..

    >
    > Either you got something really wrong here, or I don't know what you
    > want to say...


    No, what he has is perfectly correct.

    > > From TC++PL. (§C8.1): "..using (bit)fields to pack several variables

    > into
    > > a byte.."

    >
    > Yes.
    >
    > unsigned char a_byte;
    >
    > a_byte = 0; // 00000000
    >
    > a_byte |= 5; // 00000101
    > a_byte |= 2; // 00000111
    >
    >
    > >
    > > I assume a byte (or allocation unit, or word) on any platform known

    > to man
    > > has room for at least two bits, and therefore will not straddle.

    >
    > Ouch! A BYTE is defined as 8 BIT, a WORD as 2 BYTE (thus 16 BIT).


    Wrong again. There is no such thing as a 'BYTE' in the C++ language.
    There is something called a 'byte'. Here is how the C++ language
    standard defines a byte:

    "The fundamental storage unit in the C++ memory model is the byte. A
    byte is at least large enough to contain any member of the basic
    execution character set and is composed of a contiguous sequence of
    bits, the number of which is implementation-defined. The least
    significant bit is called the low-order bit; the most significant bit
    is called the high-order bit. The memory available to a C++ program
    consists of one or more sequences of contiguous bytes. Every byte has
    a unique address."

    The standard requires that a byte contain at least 8 bits, it may
    contain more. On some C++ implementations bytes contain 16 or 32
    bits.

    On the other hand, the language does not define a 'WORD' or a 'word',
    nor does it require or guarantee that any data type is either 2 bytes
    or 16 bits.

    > Both are graeter than 2 BITS, thus, yes you can store 2 bits:
    >
    >
    > >
    > > From http://www.parashift.com/c -faq-lite/intrinsic-types.html:

    > "The C++
    > > language guarantees a byte must always have at least 8 bits."

    >
    > True.
    >
    > > From the C++ standard (2003) (§9.6): "Bit fields are packed into

    > some
    > > addressable allocation unit."

    >
    > True
    >
    > > Note that I'm not taking into account the details about stuff like

    > MSB or
    > > the actual size of what's allocated and possibly padded, or ignored

    > as a
    > > value here. What I want to know is if it's guaranteed that 'a' and

    > 'b' is
    > > packed/aligned here.

    >
    > Yes, it's guaranteed. x.a (32 bits!?) then following x.b (32 bits)


    Obviously you should not respond to a post about bit-fields when you
    do not understand them.

    > > This is the output of the GDB under Linux (x86) when examining the
    > > contents of 'x':
    > >
    > >
    > > 14 x->a = 1;
    > > (gdb) x x
    > > 0x804a050: 00000000000000000000000000000000
    > > (gdb) step
    > > 15 x->b = 1;
    > > (gdb) x x
    > > 0x804a050: 00000000000000000000000000000001
    > > (gdb) step
    > > 16 return(0);
    > > (gdb) x x
    > > 0x804a050: 00000000000000000000000000000011
    > > (gdb)

    >
    > I don't know about gdb, but it seems weired...


    No, it is perfectly reasonable.

    > > Sorry if the question is wierd -- but we're having quite a

    > discussion
    > > about this and I need to be 100% sure about how this works (and

    > doesn't
    > > work).


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 27, 2004
    #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. Taylor Howell
    Replies:
    5
    Views:
    468
    Andrew Phillips
    Apr 20, 2005
  2. Replies:
    3
    Views:
    1,767
    Timothy Bendfelt
    Jan 19, 2007
  3. Mike -- Email Ignored

    Bit Order in Bit Fields

    Mike -- Email Ignored, May 2, 2009, in forum: C++
    Replies:
    0
    Views:
    384
    Mike -- Email Ignored
    May 2, 2009
  4. Shashank R Khanvilkar

    Packing/Unpacking bit fields from a byte.

    Shashank R Khanvilkar, Sep 25, 2005, in forum: Perl Misc
    Replies:
    6
    Views:
    412
    Anno Siegel
    Sep 26, 2005
  5. Replies:
    4
    Views:
    124
    Ned Batchelder
    Nov 13, 2013
Loading...

Share This Page