Bit Fields

Discussion in 'Mac Programming' started by North Bronson, Nov 7, 2010.

  1. macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #1
    Hello. If anyone could help me understand how to use these bit-fields, that would be great.

    Both of my C texts tell me that I can instantiate a struct like this:

    Code:
    #include <stdio.h>
    
    int main (int argc, char *argv[])
    {
        struct intStruct
        {
            unsigned int value0 : 1;
            unsigned int value1 : 1;
            unsigned int value2 : 1;
            unsigned int value3 : 1;
            unsigned int value4 : 1;
            unsigned int value5 : 1;
            unsigned int value6 : 1;
            unsigned int value7 : 1;
        };
        
        printf("%lu\n", sizeof(struct intStruct));
        
        return 0;	
    }
    The console tells me that this struct is four bytes long. Shouldn't it be only one byte?

    If I try this:

    Code:
    #include <stdio.h>
    
    int main (int argc, char *argv[])
    {
        struct charStruct
        {
            unsigned char value0 : 1;
            unsigned char value1 : 1;
            unsigned char value2 : 1;
            unsigned char value3 : 1;
            unsigned char value4 : 1;
            unsigned char value5 : 1;
            unsigned char value6 : 1;
            unsigned char value7 : 1;
        };
        
        printf("%lu\n", sizeof(struct charStruct));
        
        return 0;	
    }
    The console tells me that the struct is only one byte, but both of my C texts tell me not to use chars for bit-fields.

    If anyone can explain what's going on, that would be great.
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Why would the size of 8 ints be 1 byte? That would imply each int was only 1 bit so could only represent 2 values. Ints can obviously represent more values than that...
     
  3. macrumors 68040

    Joined:
    Feb 2, 2008
    #3
    The compiler might add padding to make the program faster and more efficient. You can force it to be packed with gcc, which might lead to a less efficient program but anyway. Try this.

    Code:
    #include <stdio.h>
    
    int main (int argc, char *argv[])
    {
        struct intStruct
        {
            unsigned int value0 : 1;
            unsigned int value1 : 1;
            unsigned int value2 : 1;
            unsigned int value3 : 1;
            unsigned int value4 : 1;
            unsigned int value5 : 1;
            unsigned int value6 : 1;
            unsigned int value7 : 1;
        }__attribute__((packed));
    
        printf("%lu\n", sizeof(struct intStruct));
    
        return 0;
    }
    
    
     
  4. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    To get an almost authoritative answer, google for "N1256.pdf" which will find the last free draft of the C99 Standard. From that document:

    "A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type."

    In other words, while the gcc compiler may accept bitfields of type "unsigned char", other compilers might not. Bit fields of type "unsigned int" are portable.

    On the other hand, there is no danger in using bit fields of type char or unsigned char: If the compiler accepts it then it works; if it doesn't work the compiler will tell you, so you can leave it to whoever tries to port the code to make the change (a comment would be nice so that a programmer having to fix a compiler error knows what is going on).
     
  5. thread starter macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #5
    I thought that by using bit-fields I could force the compiler to build each int into only one-bit. Isn't that the what bit-fields are supposed to be able to do?
     
  6. thread starter macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #6
    Interesting. That code that you added works and the struct is only one byte now.
     
  7. thread starter macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #7
    Good to know. I'm building this on Xcode for Snow Leopard (with GCC). I should probably check what LLVM would do with that same struct.
     
  8. subsonix, Nov 7, 2010
    Last edited: Nov 7, 2010

    macrumors 68040

    Joined:
    Feb 2, 2008
    #8
    I think the main idea it to provide an easier to use interface then dealing with bitwize operations. It also gives you the added benefit of being able to give meaningful names to the bit positions. You could just as well have used an unsigned char directly if you wanted to.

    Also, if something is 1 byte or 4 is less of a concern today and if the compiler thinks it's more efficient to align data in 32 bit boundries it will do so by adding some padding. But as you saw, it's possible to suggest that it should not be done if it's necessary for some reason.
     

Share This Page