Thread: bitfield memory question

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    26

    bitfield memory question

    Code:
    struct x_mttype   {   struct   {
                                       unsigned int type    : 5;
                                       unsigned int locale  : 1;
                                       unsigned int obs     : 1;
                                       unsigned int offset  : 9;
                                   } tilea;
                          struct   {
                                       unsigned int tchar   : 8;
                                       unsigned int palette : 5;
                                       unsigned int bright  : 1;
                                       unsigned int link    : 1;
                                       unsigned int mystery : 1;
                                   } tileb;
                          char *file;
                      };
    
    x_mttype map[19][79];
    Here I have specified the use of 16 bits in two bit fields in my main struct. When you specify a int type bit field on a 32bit machine, does the bit field use 32 bits even if you only specify 16? I'm trying to conserve memory you see.

  2. #2
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I'm not sure, but I believe the type specifier is only used for type info/interpretation reasons when dealing with bitfields, i.e. "cout << (object).palette;" will output a number as opposed to a character. However, unless you specify otherwise, the compiler is allowed to add padding bits/bytes to the end of your structure for speed optimizations (and bits will always be added to align the structure to 8-bit blocks anyway).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >When you specify a int type bit field on a 32bit machine, does
    >the bit field use 32 bits even if you only specify 16?
    Yes.

    >I'm trying to conserve memory you see.
    The easiest way to conserve memory is to use a narrower type. Bitfields have annoying restrictions, so you may find it more flexible to switch to explicit bitwise operations.
    My best code is written with the delete key.

  4. #4
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    If that's the case, then what's the point of using bit fields at all?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >then what's the point of using bit fields at all?
    None that I can see. Bitfields have portability issues and in the end aren't beneficial enough to make them worth using most of the time (in my opinion). I think they're just there as a convenient way to do basic bitwise operations with less obscure syntax.
    My best code is written with the delete key.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I'm trying to conserve memory you see.
    Well 20x80 of what you have isn't going to take up that much space, even if you do it the long way.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    But how can bitfields reliably replace bitwise operations if the specified field sizes are ignored? After all, that seems to somewhat defeat the purpose (or even definition) of bitfields.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Given
    Code:
    struct x_mttype   {   struct   {
                                       unsigned int type    : 5;
                                       unsigned int locale  : 1;
    The only thing you can say about type is that it can store small unsigned integers in the range 0..31
    The only thing you can say about locale is that it is 0 or 1.

    What you can't say is
    - how big x_mttype is
    - which bits of x_mttype are used to store type and locale
    - whether there is any padding bits between type and locale

    If you have lots of small values, then bit-fields can save data space (possibly at the expense of more complex code to access it). The space saving argument was good when
    - processors had less than 1MB of total memory (say 64K in the original platform on which C was developed)
    - there was only one implementation of C, and everyone understood how bit-fields were arranged.

    But nowadays, the memory saving argument only really applies if you're on very memory limited embedded devices. Standard desktops should not have a problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Mar 2004
    Posts
    220
    So, what's the complex code that would access larger variables?

    Also, why can't
    Code:
    struct foobar { unsigned int foo : 5; }
    be of a 5-bit size, and not a regular 32-bits? What's the reason for the restriction? Is there any way that variables can be a size that the programmer wants, without taking up 27-bits that are never going to be used?
    OS: Windows XP Pro CE
    IDE: VS .NET 2002
    Preferred Language: C++.

  10. #10
    Registered User
    Join Date
    Mar 2005
    Posts
    26
    Eventually in my roguelike game I plan to have have the game system update the underground board at the same time as the above ground board, so that monsters can come out of a passage from the catacombs; more realistic. This means I'll need double the space of 20 * 80 in memory at one time. So you see, I need to minimize memory being used. It's generally not acceptable to use more than 16 kb for a board. I also will need to store a pointer to a char type so that I can allow the user to specify a file name to link the board. The pointer is 4 bytes, so that's 4 * 80 * 20 added on. And then I need another 4 byte integer to specify the skill type needed to traverse the terrain type on the map.

    This is a platform specific dev. I don't approve of multiple op systems. They only had ONE on Star Trek, so I don't see how we need to be any different. Since Windows XP is now the most popular, I will cater for that.

    Instead of specifying a char fn[11] which will take up 24 bytes * 80 * 20, it's more efficient to use a pointer, since not every tile is going to link to a board. That reduces the cost from 24 bytes to 4 bytes.
    Last edited by sufthingol; 03-24-2005 at 03:27 PM.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    What is the reason for two adjacent structures of bitfields...
    Code:
       struct
       {
          unsigned int type    : 5;
          unsigned int locale  : 1;
          unsigned int obs     : 1;
          unsigned int offset  : 9;
       } tilea;
       struct
       {
          unsigned int tchar   : 8;
          unsigned int palette : 5;
          unsigned int bright  : 1;
          unsigned int link    : 1;
          unsigned int mystery : 1;
       } tileb;
    ...rather than a single structure of bitfields?
    Code:
       struct
       {
          unsigned int type    : 5;
          unsigned int locale  : 1;
          unsigned int obs     : 1;
          unsigned int offset  : 9;
    
          unsigned int tchar   : 8;
          unsigned int palette : 5;
          unsigned int bright  : 1;
          unsigned int link    : 1;
          unsigned int mystery : 1;
       } tile;
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User
    Join Date
    Mar 2004
    Posts
    220
    sufthingol you might want to try dividing up the 32-bits for the integers, and using lets say the first four bytes for one thing, the next 5 for another thing, the next 6 for another thing, etc. I don't recall how to do this but if I ever remember I'll come back to this thread and edit it.
    OS: Windows XP Pro CE
    IDE: VS .NET 2002
    Preferred Language: C++.

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > So, what's the complex code that would access larger variables?
    Given a 5-bit bit-field, the compiler could well generate for

    resullt = bit_field.var;

    as the following sequence...
    int temp = bit_field_var & 0x1f00;
    temp = temp >> 8;
    result = temp;

    And likewise, the reverse to assign a value.

    This is obviously more involved than simply saying
    result = field.var
    as a simple assignment of regular sized variables.

    > be of a 5-bit size, and not a regular 32-bits?
    Because everything has to be at least a multiple of sizeof(char) in size. Processors cannot address bits directly, only via the bitwise operators do you get that level of control.
    bit-fields merely give a convenient syntax for all that & | << and >> you could otherwise do to extract and insert bits.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>everything has to be at least a multiple of sizeof(char) in size.
    Right, but why is it forced to 32 bits (as opposed to 8), or is that a typo?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by Hunter2
    >>everything has to be at least a multiple of sizeof(char) in size.
    Right, but why is it forced to 32 bits (as opposed to 8), or is that a typo?
    Salem can explain it better, but in a word, speed. Most compilers for 32-bit machines will align data to 32-bit boundaries.

    However I believe most compilers have a way to allow packing, a pragma or something.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer memory question
    By Edo in forum C++ Programming
    Replies: 5
    Last Post: 01-21-2009, 03:36 AM
  2. Memory question
    By John_L in forum Tech Board
    Replies: 8
    Last Post: 06-02-2008, 10:06 PM
  3. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  4. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  5. I have a Question about memory usage for C.
    By bobthefish3 in forum C Programming
    Replies: 34
    Last Post: 12-24-2001, 04:37 PM