Thread: Storing an integer in a struct

  1. #1
    Registered User
    Join Date
    Mar 2019
    Posts
    1

    Storing an integer in a struct

    I am trying to store a 16 big integer inside a struct, I'd like to know if there is a fast way of doing so?
    Code:
    struct memstatreg
    {
        unsigned int a:1;
        unsigned int b:1;
        unsigned int c:1;
        unsigned int d:5;
        unsigned int e:3;
        unsigned int f:1;
        unsigned int g:4; //16bits 
    }F_STATUS;
    
    unsigned int i=0x7BAB; // eq. 0111101110101011b
    my result should be :

    |_g__|f|__e_|__d__|c|b|a|
    |0111|1|011|10101|0|1|1|

    I think since each variable in the struct is declared unsigned int, this preserves 16*7(128) bits in memory and setting F_STATUS=i would mean trying to equate 128bits in memory with 16 bits?
    The only method i can think of is using bitwise operations which is fine for me however the code can get quite messy.

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Code:
    union fields_u {
      unsigned short value;
    
      // Anonymous structure...
      struct {
        unsigned short a:1;
        unsigned short b:1;
        unsigned short c:1;
        unsigned short d:5;
        unsigned short e:3;
        unsigned short f:1;
        unsigned short g:4;
      };
    };
    
    // Usage:
    union fields_u x;
    
    x.value = 0x7bab;
    
    // print the fields:
    printf( "a:%u, b:%u, c:%u, d:0x%hx, e:0x%hx, f:%u, g:0x%hx\n",
      x.a, x.b, x.c, x.d, x.e, x.f );
    But, be careful... bit fields can be tricky. I advise to use the attribute 'packed' (or the pragma 'pack') to garantee the bits are tighter as possible...

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by rsswd1744 View Post
    I think since each variable in the struct is declared unsigned int, this preserves 16*7(128) bits in memory and setting F_STATUS=i would mean trying to equate 128bits in memory with 16 bits?
    No no, bitfields don't work that way. The compiler keeps track of the amount of bits you have assigned to each member, and does the appropriate bitwise calculations behind the scenes. Your struct's size will always be a multiple of the type you used to make the bitfields from, "unsigned int" in this case.

    Here, a single "unsigned int" would be used (in memory I mean), which would contain all of the members inside it. If your bitfield is neatly packed, each member literally represents the bits you assigned it to.
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    A small correction on my last comment: pragma "pack" refers to types alignment, not bit packing.

    The standard tells us about bit fields, but it says bit packing is "implementation dependant". So, it is advisable to use the compiler extension, if there is one, to pack them as tight as possible:
    Code:
    union fields_u {
      unsigned short value;
     
      // Anonymous structure...
      struct {
        unsigned short a:1; // this could be a single bit followed by 15 unused bits...
        unsigned short b:1;
        unsigned short c:1;
        unsigned short d:5; // this could be 5 useful bits followed by 11 unused bits...
        unsigned short e:3; // this could be 3 useful bits followed by 13 unused bits...
        unsigned short f:1;
        unsigned short g:4; // this could be 4 useful bits followed by 12 unused bits...
      } __attribute__((packed)); // this packs everything as tight as possible....
    };
    This __attribute__((packed)) is available only on GCC. Visual Studio and other compilers may have different ways to do the same thing...

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Quote Originally Posted by flp1969 View Post
    The standard tells us about bit fields, but it says bit packing is "implementation dependant"
    Nope. Bits are always "packed" if possible (that's the whole point!). "If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit." (n1256 6.7.2.1:10)

    However, it is implementation defined whether you can use a short. And of course the endianness will be a factor in your union trick.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by john.c View Post
    Nope. Bits are always "packed" if possible (that's the whole point!). "If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit." (n1256 6.7.2.1:10)

    However, it is implementation defined whether you can use a short. And of course the endianness will be a factor in your union trick.
    Yep... strangely only _Bool, signed and unsigned int (by 6.7.2.1:4) are garanteed (_Bool?! 6.2.5 defines as "large enough to store 0 or 1"!!!).

    But 6.7.2.1:10 states:

    An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit...

    Everything else is implementation defined.

    So, bits-fields are not always packed!

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    I'm not going to argue with someone who can't admit when he's wrong. I'll leave you to babble your nonsense from now on. I simply don't f'ing care anymore.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    my result should be :

    |_g__|f|_e_|__d__|c|b|a|
    |0111|1|011|10101|0|1|1|
    Your result could be this
    |a|b|c|__d__|_e_|f|__g_|
    |1|1|0|10101|011|1|0111|


    Some compilers allocate from the LSB first, and others from the MSB first. But unlike flip's imaginary packing problem, there is no magic flag to fix the allocation ordering.

    > The only method i can think of is using bitwise operations which is fine for me however the code can get quite messy.
    If you're trying to pick apart some external data source, it's the only way to go if you want portable code.

    With 7 fields, perhaps a table-driven approach becomes a viable alternative.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Storing integer into character array
    By ajitnayak87 in forum C Programming
    Replies: 1
    Last Post: 06-06-2016, 06:18 AM
  2. Storing Multiple Bits as One Integer
    By Lilith Matthews in forum C Programming
    Replies: 9
    Last Post: 10-03-2013, 07:38 PM
  3. Storing user input into integer array
    By samii1017 in forum C Programming
    Replies: 2
    Last Post: 10-28-2012, 03:31 PM
  4. Storing an integer in an array using getchar
    By Interista in forum C Programming
    Replies: 9
    Last Post: 11-04-2011, 12:37 PM
  5. storing integer values in files using WriteFile
    By Fender Bender in forum Windows Programming
    Replies: 1
    Last Post: 01-15-2006, 12:15 AM

Tags for this Thread