Thread: need help in bit field

  1. #16
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by lovesunset21 View Post
    Thanks so much. Can you explain the UNION keyword for me?
    I already did... It's just a special kind of struct where instead of all the variables being separate, they lay on top of one another, literally occupying the same address space.

    testvar.MyByte is 1 byte long at the same address as the unnamed char with the 8 bits.... Change one, you change the other.

  2. #17
    Registered User
    Join Date
    Oct 2010
    Posts
    37
    actually, when I try this:



    testvar.b2 = 1;
    printf("We got %d",testvar.MyByte); // = 4
    It is 1, not 4. It should be 4, right?

  3. #18
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well the entire idea of using bit-fields to pull the bits out of a byte is broken to begin with.

    There is NOTHING in the standard which says that your b1 (for example) should correspond to say the lsb of a byte.

    If you want to be sure of getting the lsb, then you have to use something like
    byte & 0x01
    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.

  4. #19
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by lovesunset21 View Post
    actually, when I try this:
    It is 1, not 4. It should be 4, right?
    Did you create the union exactly as I showed you?
    It should work....

  5. #20
    Registered User
    Join Date
    Oct 2010
    Posts
    37
    Quote Originally Posted by CommonTater View Post
    Did you create the union exactly as I showed you?
    It should work....
    Yes, of course, I copy and paste


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    typedef union t_byte_s
    { unsigned char MyByte;
       unsigned char b0:1,
                    b1:1,
                    b2:1,
                    b3:1,
                    b4:1,
                    b5:1,
                    b6:1,
                    b7:1; }
           byte_s;
    int main(void) {
    	byte_s testvar;
    
    	testvar.MyByte = 127;
    
    	if (testvar.b6)
    	  puts ("eyup, it's a 1");
    
    	testvar.MyByte = 0; // clear the bits
    
    	testvar.b2 = 1;
    	printf("We got %d",testvar.MyByte);  // = 4
    	return EXIT_SUCCESS;
    }

  6. #21
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Hmmm... if you're doing b3 you should get 8.

    It works here... (on PellesC).

  7. #22
    Registered User
    Join Date
    Oct 2010
    Posts
    37
    Quote Originally Posted by CommonTater View Post
    Hmmm... if you're doing b3 you should get 8.

    It works here... (on PellesC).
    That's right. It should be 8, but it is alway 1. I am running it on Eclipse and Ubuntu

  8. #23
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by lovesunset21 View Post
    That's right. It should be 8, but it is alway 1. I am running it on Eclipse and Ubuntu
    Ok... now something of a mystery... I copied and pasted your code... and I get 1 all the time...

    WEIRD!

    Maybe Salem is right...

  9. #24
    Registered User
    Join Date
    Oct 2010
    Posts
    37
    What should we add into the code as Salem told? I am a dummy C. Therefore, I don't really understand his idea. Thanks

  10. #25
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Each member of a union shares the same space. So it stands to reason that if you have multiple bit fields directly in the union, they represent separate members and thus refer to the same spot in memory. You can get a more meaningful result by wrapping the bit fields in a separate structure such that the bits are represented by a single member in the union:
    Code:
    #include <stdio.h>
    
    struct bit_set {
        unsigned b0:1;
        unsigned b1:1;
        unsigned b2:1;
        unsigned b3:1;
    
        unsigned b4:1;
        unsigned b5:1;
        unsigned b6:1;
        unsigned b7:1;
    };
    
    union byte {
        unsigned char source;
        struct bit_set bits;
    };
    
    int main(void)
    {
        union byte testvar;
    
        testvar.source = 'A';
    
        printf("%d%d%d%d %d%d%d%d\n", 
            testvar.bits.b7, testvar.bits.b6, 
            testvar.bits.b5, testvar.bits.b4, 
            testvar.bits.b3, testvar.bits.b2, 
            testvar.bits.b1, testvar.bits.b0);
    
        return 0;
    }
    My best code is written with the delete key.

  11. #26
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Alrighty.... give this a try....

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef union t_var
    { unsigned char MyByte;
      struct t_bits  
        { unsigned char b0 : 1,
                        b1 : 1,
                        b2 : 1,
                        b3 : 1,
                        b4 : 1,
                        b5 : 1,
                        b6 : 1,
                        b7 : 1; } bits; }
                                  tvar;
    
    
    int main(void) 
      { tvar testvar;
    
        testvar.MyByte = 56;
    
        printf("%d%d%d%d %d%d%d%d = %d \n",
                  testvar.bits.b7,testvar.bits.b6,testvar.bits.b5,testvar.bits.b4,
                  testvar.bits.b3,testvar.bits.b2,testvar.bits.b1,testvar.bits.b0,
                  testvar.MyByte);
    
                  // output : 0011 1000 = 56
    
    	 testvar.MyByte = 0; // clear the bits
    
    	 testvar.bits.b2 = 1;
    	 printf("We got %d\n\n",testvar.MyByte);  // = 4
             testvar.bits.b4 = 1;
    	 printf("We got %d\n\n",testvar.MyByte);  // = 20
     
       return EXIT_SUCCESS;
    }
    The problem appears to be that without the nested struct, the union was laying all the bits on top of each othe as well....
    Last edited by CommonTater; 10-30-2010 at 04:54 PM.

  12. #27
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Prelude View Post
    Each member of a union shares the same space. So it stands to reason that if you have multiple bit fields directly in the union, they represent separate members and thus refer to the same spot in memory. You can get a more meaningful result by wrapping the bit fields in a separate structure such that the bits are represented by a single member in the union:
    LOL... great timing... I was working on that very thing as you posted this.

    One might reasonably expect that coming from a single char as the root variable, they wouldn't pile up like that.
    Doesn't explain how I had it working here...

    Live and Learn.
    Last edited by CommonTater; 10-30-2010 at 05:00 PM.

  13. #28
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Well... been playing with this a little more and WOW what a learning experience.

    Only problem is that now I've got to go revise a bunch of code where I'm using bitfields incorrectly... Bummer.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. bit level permutation function
    By zxcv in forum C Programming
    Replies: 2
    Last Post: 07-27-2008, 01:26 PM
  2. Porting from 32 bit machine to 64 bit machine!
    By anoopks in forum C Programming
    Replies: 10
    Last Post: 02-25-2005, 08:02 PM
  3. Replies: 7
    Last Post: 12-10-2004, 08:18 AM
  4. BIT field confusing
    By C-Dumbie in forum C Programming
    Replies: 4
    Last Post: 09-14-2002, 02:33 AM
  5. linked lists problem
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 06-17-2002, 10:55 AM