On bit fields usage

Discussion in 'C Programming' started by bitshadow, Aug 27, 2007.

  1. bitshadow

    bitshadow Guest

    Hi all,
    I'm implementing RFC3550 that requires me to create a header of n
    number of bits. I've used a bit field to accomplish this. however i
    realise i know little about bit fields and my C primer Plus doesn't go
    into too much detail..

    assuming i have the following structure:

    typedef struct{
    unsigned int v: 2;/*rtp version*/
    unsigned int p: 1; /*rtp padding*/
    unsigned int x: 1;/*extension bit*/
    unsigned int cc: 4;/*csrc count*/
    unsigned int m: 1;/*marker bit*/
    unsigned int pt: 7;/*payload type*/
    unsigned int sn: 16;/*sequence number*/
    unsigned int ts: 32;/*time stamp*/
    unsigned int ssrc: 32;/*synchronization source*/
    unsigned int csrc: 32;/*contributing sources max 15*/
    char *encoded_audio;
    }rtp_hdr;

    1)I understand that the bit field is just stored as an unsigned
    integer and the total value of the bit field can't exceed the sizeof
    unsigned int (32 bits) or 4 bytes is this correct?

    2)assuming i have the above structure does that mean then that the
    char variable - holding 40 bytes - would run into the first bit int v?


    3)if i don't decalare a type and simply do:

    typedef struct{
    unsigned v: 2;/*rtp version*/
    unsigned p: 1; /*rtp padding*/
    unsigned x: 1;/*extension bit*/
    unsigned cc: 4;/*csrc count*/
    unsigned m: 1;/*marker b*
    .......}

    will the compiler automatically declare them as unsigned int?

    4)in order to make sure the amount of bits i need fits into the
    header struct does that mean i have to implicity declare short
    integers to make them fit.

    5)will my compiler store the bits in the way they are layed out or is
    it compiler dependant.

    thank you, i know its alot of questions (it's not homework) i just
    want to make sure i understand how these work
    so i can build this.

    thank you very much,
    Greg
    bitshadow, Aug 27, 2007
    #1
    1. Advertising

  2. bitshadow <> writes:
    > I'm implementing RFC3550 that requires me to create a header of n
    > number of bits. I've used a bit field to accomplish this. however i
    > realise i know little about bit fields and my C primer Plus doesn't go
    > into too much detail..
    >
    > assuming i have the following structure:
    >
    > typedef struct{
    > unsigned int v: 2;/*rtp version*/
    > unsigned int p: 1; /*rtp padding*/
    > unsigned int x: 1;/*extension bit*/
    > unsigned int cc: 4;/*csrc count*/
    > unsigned int m: 1;/*marker bit*/
    > unsigned int pt: 7;/*payload type*/
    > unsigned int sn: 16;/*sequence number*/
    > unsigned int ts: 32;/*time stamp*/
    > unsigned int ssrc: 32;/*synchronization source*/
    > unsigned int csrc: 32;/*contributing sources max 15*/
    > char *encoded_audio;
    > }rtp_hdr;
    >
    > 1)I understand that the bit field is just stored as an unsigned
    > integer and the total value of the bit field can't exceed the sizeof
    > unsigned int (32 bits) or 4 bytes is this correct?


    The value of an unsigned int bitfield of width N cannot exceed 2**N-1.
    The value of N cannot exceed the width of type unsigned int, which may
    or may not be 32 bits; it can be as small as 16 bits, or it can be
    arbitrarily wide.

    > 2)assuming i have the above structure does that mean then that the
    > char variable - holding 40 bytes - would run into the first bit int v?


    You don't have a char variable holding 40 bytes. You have a char*
    member which may point to the first element of an array, which may
    hold 40 bytes. But the encoded_audio pointer isn't going to point
    to anything until you assign a value to it.

    But I don't think that's what you want.

    For one thing, the standard leaves a lot of leeway in how bit fields
    are allocated. For details, see the C standard; the latest post-C99
    draft is available at
    <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>. You
    can't be sure that your bit fields will be laid out as required by the
    RFC.

    You also have to worry about byte ordering. The RFC probably requires
    a specific representation for each field (probably "network byte
    order"); your platform may or may not use that same representation.

    For portability, you may have better luck using explicit bitwise
    shifts and masks to access the individual fields, rather than
    declaring bit fields and hoping that the compiler will generate those
    same shifts and masks for you. But if you find that bit fields work,
    the convenience just might be worth the potential loss of portability.

    Taking a very quick look at RFC 3550, you've defined a structure
    that's intended to match the "RTP header", which will be followed
    directly in memory by other information. Rather than having the extra
    information in your structure, you have a pointer.

    This might be a job for the "struct hack" (see question 2.6 in the
    comp.lang.c FAQ, <http://c-faq.com/>), or for a "flexible array
    member" if your compiler supports this C99 feature.

    But it's probably better for your structure to hold just what's
    defined for the RTP header. You can then declare another structure
    type for each kind of packet, each of which will have a header
    structure as its first member.

    > 3)if i don't declare a type and simply do:
    >
    > typedef struct{
    > unsigned v: 2;/*rtp version*/
    > unsigned p: 1; /*rtp padding*/
    > unsigned x: 1;/*extension bit*/
    > unsigned cc: 4;/*csrc count*/
    > unsigned m: 1;/*marker b*
    > ......}
    >
    > will the compiler automatically declare them as unsigned int?


    Yes, the names 'unsigned int' and 'unsigned' are simply different
    names for the same type. If you've grabbed a copy of n1124.pdf, see
    section 6.7.2, "Type specifiers".

    > 4)in order to make sure the amount of bits i need fits into the
    > header struct does that mean i have to implicity declare short
    > integers to make them fit.


    No. The only portably supported types for bit fields are int, signed
    int, unsigned int, and (C99 only) _Bool. (In most contexts, 'int' and
    'signed int' are identical; for bit fields, 'int' may be either signed
    or unsigned, at the whim of the compiler. Because of this, don't use
    plain int for bit fields.)

    > 5)will my compiler store the bits in the way they are layed out or is
    > it compiler dependant.


    It's compiler dependent.

    I'd be surprised if nobody else had already written a C implementation
    of RFC 3550. A little bit of Googling could save you a lot of time
    and effort (since you say this isn't homework).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Aug 27, 2007
    #2
    1. Advertising

  3. bitshadow

    bitshadow Guest

    On Aug 27, 4:21 pm, Keith Thompson <> wrote:
    > bitshadow <> writes:


    >
    > I'd be surprised if nobody else had already written a C implementation
    > of RFC 3550. A little bit of Googling could save you a lot of time
    > and effort (since you say this isn't homework).
    >
    > --
    > Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    > San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Hi keith,
    thanks for replying, i'll have a look over what you said and test it
    out.
    *lol* it honestly isn't homework and there actually are quite a few
    libraries out there, however i want to learn about bit fields
    and how to manipulate bits and i also want to write RFC3550 directly
    into my voip code to make it a little more tight.
    bitshadow, Aug 27, 2007
    #3
  4. bitshadow <> writes:
    > On Aug 27, 4:21 pm, Keith Thompson <> wrote:
    >> bitshadow <> writes:
    >> I'd be surprised if nobody else had already written a C implementation
    >> of RFC 3550. A little bit of Googling could save you a lot of time
    >> and effort (since you say this isn't homework).

    >
    > thanks for replying, i'll have a look over what you said and test it
    > out.
    > *lol* it honestly isn't homework and there actually are quite a few
    > libraries out there, however i want to learn about bit fields
    > and how to manipulate bits and i also want to write RFC3550 directly
    > into my voip code to make it a little more tight.


    Please don't quote signatures (the portion of the article following
    the "-- " marker" unless you're actually commenting on them. The
    attribution line ("So-and-so <> wrote:") is sufficient to
    identify who you're quoting.

    You'll find that bit fields and "how to manipulate bits" are two
    different things, at least if you want your code to be portable.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Aug 28, 2007
    #4
  5. bitshadow

    bitshadow Guest

    On Aug 27, 4:21 pm, Keith Thompson <> wrote:

    > You don't have a char variable holding 40 bytes. You have a char*
    > member which may point to the first element of an array, which may
    > hold 40 bytes. But the encoded_audio pointer isn't going to point
    > to anything until you assign a value to it.
    >
    > But I don't think that's what you want.
    >
    >Why don't you think thats what i want? you said it'd be better if i declared another struct to hold the data being sent is there

    any problems with doing this:

    typedef struct{
    rtp_hdr Header;/*modularize for ease of use and no truncating to
    unsigned int?*/
    char *audio;/*does it matter if i malloc the data or hard code it?*/
    }Payload;

    before the data is sent i malloc a buffer and fill it with data.
    however doing this is it sill being 'corrupted'
    somehow? do i have to declare the (char *) in a separate struct so its
    not counted as part of the bit field? or is that declaration
    okay as long as i malloc it before sending.

    as for the way the bits are layed out by the compiler i will be
    checking with my compiler doc for that and the link you gave me as
    well. intriguing.
    bitshadow, Aug 28, 2007
    #5
  6. bitshadow <> writes:
    > On Aug 27, 4:21 pm, Keith Thompson <> wrote:
    >> You don't have a char variable holding 40 bytes. You have a char*
    >> member which may point to the first element of an array, which may
    >> hold 40 bytes. But the encoded_audio pointer isn't going to point
    >> to anything until you assign a value to it.
    >>
    >> But I don't think that's what you want.
    >>

    > Why don't you think thats what i want? you said it'd be better if i
    > declared another struct to hold the data being sent is there any
    > problems with doing this:
    >
    > typedef struct{
    > rtp_hdr Header;/*modularize for ease of use and no truncating to
    > unsigned int?*/
    > char *audio;/*does it matter if i malloc the data or hard code it?*/
    > }Payload;


    You're trying to match the data layout defined by RFC whatever-it-was.
    I'm 99% certain that the RFC doesn't specify a pointer (i.e., an
    internal memory address) in any of its packet definitions.

    Pointers are for use in your program to refer to data in memory. If
    you're trying to write a pointer to a file, or to a network, or
    something similar, you're doing something wrong.

    One possible source of confusion is that arrays and pointers can
    *appear* to be similar, or even the same thing. They are not. Arrays
    are not pointers; pointers are not arrays. For more information on
    this, see section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>.
    (I typed the URL and section number from memory, since I don't have a
    browser running.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Aug 28, 2007
    #6
  7. bitshadow <> writes:

    > On Aug 27, 4:21 pm, Keith Thompson <> wrote:

    <snip>
    >> But I don't think that's what you want.
    >>
    >>Why don't you think thats what i want? you said it'd be better if i declared another struct to hold the data being sent is there

    > any problems with doing this:
    >
    > typedef struct{
    > rtp_hdr Header;/*modularize for ease of use and no truncating to
    > unsigned int?*/
    > char *audio;/*does it matter if i malloc the data or hard code it?*/
    > }Payload;
    >
    > before the data is sent i malloc a buffer and fill it with data.
    > however doing this is it sill being 'corrupted'
    > somehow? do i have to declare the (char *) in a separate struct so its
    > not counted as part of the bit field? or is that declaration
    > okay as long as i malloc it before sending.


    The corruption will, most likely, be coming from something else. The
    structures are fine.

    What Keith Thompson was most likely referring to when he said "but I
    don't think that's what you want" is that in most network code, one
    puts the header and payload in one contiguous block of memory because
    this (except on *very* interesting hardware) simplifies the interface
    to lower-level send and receive functions.

    --
    Ben.
    Ben Bacarisse, Aug 29, 2007
    #7
  8. bitshadow

    bitshadow Guest

    On Aug 28, 6:14 pm, Ben Bacarisse <> wrote:

    > What Keith Thompson was most likely referring to when he said "but I
    > don't think that's what you want" is that in most network code, one
    > puts the header and payload in one contiguous block of memory because
    > this (except on *very* interesting hardware) simplifies the interface
    > to lower-level send and receive functions.
    >

    Thanks for your reply ben and clarifying that up for me. the previous
    code only sends 20bytes even aftter i've malloced and added the
    payload and i was wondering where i could have possibly gone wrong. it
    tells me the bit field is 20 bytes, the (char *) is four and then the
    bytes sent is 20. that means somehow it seems not to be mallocing the
    required amount or perhaps not adding the audio i need.

    Could it be then its better to hard code the size of the payload since
    that will save it one contiguous block of memory: ex:
    typedef struct{
    rtp_hdr Header;
    char audio[MAX_LEN];
    }Payload;

    is that what you mean by putting the header and payload in one
    contiguous block of memory, since if i malloc it i can't gurantee
    where it will be.

    Thank you very much,
    Greg
    bitshadow, Aug 29, 2007
    #8
  9. bitshadow <> writes:

    > On Aug 28, 6:14 pm, Ben Bacarisse <> wrote:
    >
    >> What Keith Thompson was most likely referring to when he said "but I
    >> don't think that's what you want" is that in most network code, one
    >> puts the header and payload in one contiguous block of memory because
    >> this (except on *very* interesting hardware) simplifies the interface
    >> to lower-level send and receive functions.
    >>

    > Thanks for your reply ben and clarifying that up for me. the previous
    > code only sends 20bytes even aftter i've malloced and added the
    > payload and i was wondering where i could have possibly gone wrong. it
    > tells me the bit field is 20 bytes, the (char *) is four and then the
    > bytes sent is 20. that means somehow it seems not to be mallocing the
    > required amount or perhaps not adding the audio i need.


    All this is rather unclear. I suspect there may be something wrong
    with the code that does the allocation. Showing only struct
    declarations does not give enough information.

    If the error is in standard stuff like allocation and freeing,
    bitfield setting and so on then it is topical here. Best would be a
    short compilable example that shows something going wrong.

    If the error is in the send/receive protocol stuff, you should post in
    a group that discuss your platform/

    > Could it be then its better to hard code the size of the payload since
    > that will save it one contiguous block of memory: ex:
    > typedef struct{
    > rtp_hdr Header;
    > char audio[MAX_LEN];
    > }Payload;


    That is often done. Whether it is "better" depends on too many things
    to be answerable!

    > is that what you mean by putting the header and payload in one
    > contiguous block of memory, since if i malloc it i can't gurantee
    > where it will be.


    Yes. The second part of that, suggests that you might be having
    trouble making sure that you are send the data you want to send.
    There is not problem having the data in a separate buffer, but you
    would then, usually, be sending in two parts -- the header (minus the
    'char *' field which is meaningless when sent) and the data pointer to by the
    'char *' field.

    --
    Ben.
    Ben Bacarisse, Aug 29, 2007
    #9
  10. bitshadow

    bitshadow Guest

    On Aug 29, 10:30 am, Ben Bacarisse <> wrote:
    > bitshadow <> writes:
    > > On Aug 28, 6:14 pm, Ben Bacarisse <> wrote:

    >
    >

    Thanks alot ben, for simplicities(sp?) sake i just declared a buffer
    size for the payload so i don't have to worry too much about memory
    managment. I'll attack the bit format in my compiler forum and verify
    to make sure there is nothing wrong on the network side of things as
    well.
    thanks to you both.
    bitshadow, Aug 29, 2007
    #10
    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. metfan
    Replies:
    2
    Views:
    4,832
    Robert Olofsson
    Oct 21, 2003
  2. Replies:
    3
    Views:
    1,714
    Timothy Bendfelt
    Jan 19, 2007
  3. Replies:
    9
    Views:
    938
    Juha Nieminen
    Aug 22, 2007
  4. Mike -- Email Ignored

    Bit Order in Bit Fields

    Mike -- Email Ignored, May 2, 2009, in forum: C++
    Replies:
    0
    Views:
    366
    Mike -- Email Ignored
    May 2, 2009
  5. Jeff.M
    Replies:
    6
    Views:
    162
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page