Thread: Structures and bitwise operations

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    Structures and bitwise operations

    This is related to two of my previous posts.

    http://cboard.cprogramming.com/showthread.php?t=78726
    http://cboard.cprogramming.com/showthread.php?t=78725

    I got some flak for using ugly casting to hack into the address of a member structure of a class.

    So I revised it somewhat and here is what I plan to do.
    I have a structure all of whose member variables are bitfields:
    Code:
    struct x
    {
    	UINT a:1;
    	...
    	UINT n:1;
    };
    The structure above is invoked in a class definition:
    Code:
    class y
    {
    public:
    	x some_str;
    };
    What I need to do is compare two classes by seeing how they differ in terms of the member structures. I could of course do it one by one
    Code:
    	int comp[n];
    	int[0] = y_inst_a.some_str.a ^ y_inst_a.some_str.a;
    	...
    	int[n-1] = y_inst_a.some_str.n ^ y_inst_a.some_str.n;
    First, the above is too long, and at the moment, I don't really know how many member variables I need in the structure at the moment.

    Initially, I just accessed the memory of the structure directly to initialize and invoke its value:
    Code:
    	//At the moment, the structure has less than eight values so I think using an unsigned character to represent it might be safe.
    	//constructor
    	y(){*(unsigned char*)(&some_str) = 0;}
    	unsigned char* val(){return (unsigned char*)&some_str;}
    The most obvious worry is that the data could be corrupted around the stack but maybe there are tons more stuff I should be worried about (I'm not very experienced).

    So after racking my brain a bit, the safest solution seemed to be to define an unsigned character and use that as the dumping ground for the structure values.
    Code:
    class y
    {
    public:
    	y(){some_str = (x*)&c;}
    	x* some_str; //it's a pointer this time
    	char c;
    };
    I haven't compiled the above yet so I don't know if it'll crash or not, but I really can't see a problem with it.

    If the above "hack" is problematic, could anyone help me out as to how I could make the class comfortable use but safe as well?

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You could use unions to convert structures to integers like this:

    Code:
    typedef union{
         short asShort;
         struct{
             unsigned short L:4;
             unsigned short B:4;
             unsigned short R:4;
             unsigned short F:4;
         };
         struct{
             unsigned short W:4;
             unsigned short S:4;
             unsigned short E:4;
             unsigned short N:4;
         };
    }mazeU;
    This enables you to treat mazeU as a struct with members L, B, R, and F; as a struct with members W, S, E, and N; or a stort int.

    That's for C; C++ could add some eligance to that. For example:


    You could allow casting to short like this:
    Code:
    class mazeD{
         protected:
             unsigned short L:4;
             unsigned short B:4;
             unsigned short R:4;
             unsigned short F:4;
         public:
            operator short() const {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L}
    };
    Further more, you can overload the bitwise operators themselves like this:
    Code:
    class mazeD{
         protected:
             unsigned short L:4;
             unsigned short B:4;
             unsigned short R:4;
             unsigned short F:4;
         public:
            mazeD();//defult constructor
            mazeD(mazeD&);//copy constructor
            friend const mazeD operator^ (const mazeD&, const mazeD&);
    };
    
    const mazeD operator^ (mazeD Obj1, const mazeD& Obj2)
    {
        Obj1.L^=Obj2.L
        Obj1.B^=Obj2.B
        Obj1.R^=Obj2.R
        Obj1.F^=Obj2.F
        return Obj1;
    }



    I'm a little confuse about what you're trying to do, however.
    Last edited by King Mir; 05-04-2006 at 01:51 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    You could allow casting to short like this:
    class mazeD{
    protected:
    unsigned short L:4;
    unsigned short B:4;
    unsigned short R:4;
    unsigned short F:4;
    public:
    operator short() const {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L}
    };
    Actually, that is what I'm trying not to do.
    You're calling each bitfield variable by name.

    Since I have no idea how many bitfield variables I'm going to have at the moment (though I know they're each going to be only size 1), I don't want to have to rummage through the entire code correcting each section. I just have to have access to the whole thing in one go, regardless of how many variables are inside it (within a reasonable limit).

    So if the bitfields were in address 0x00000000 to 0x00000001, I want to initialize it by assigning (int) 0 to each address, instead of assigning 0 to each bitfield value.

    Of course, if I were coding in python, I could do something like
    Code:
    for bitfield in structure:
    	bitfield = 0
    Unfortunately, in c++, I have to call each bitfield and assign a value.

    And when I access it later, I don't need to know each bitfield value.
    I just need to know the entire numeric value representing the structure.

    For example, an instance of structure X might look like 00100001 in binary. And another instance of structure X might look like 01000001. All I need to do is apply an XOR operation so I know that the structures differ in two places.

    As I mentioned before, I know how to do it. I just don't know if I'm doing it safely.



    One other question. This function is pretty funky:
    Code:
    operator short() const {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L}
    I don't really understand it. Could you explain what it's doing?
    (I understand the {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L} part. I'm just curious what "operator short() const" is.
    Last edited by cunnus88; 05-04-2006 at 02:08 PM.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Well the union meathod would still work. The only problem with it, is that the order of the members is undefined. You would either have to test your compiler to find the order, or the convertion would only make sence for being asigned the values of 0, -1, or ~0(same as -1).

    Or you could just use the bitset template from the STL. There is even a reset meathod, that sets all the bits to 0.



    One other question. This function is pretty funky:
    Code:
    operator short() const {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L}
    I don't really understand it. Could you explain what it's doing?
    (I understand the {return ((short)F<<12)+((short)R<<8)+((short)b<<4)+L} part. I'm just curious what "operator short() const" is.
    It allows you to cast the class into a short int. That way you could treat your object like a short int.

    For example you could do things like: 5+myMazeD or even 3.2+myMazeD (becouse myMazeD is first converted to a short then to a double)
    Last edited by King Mir; 05-04-2006 at 02:33 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structures - Unions
    By AProg in forum C Programming
    Replies: 16
    Last Post: 05-27-2003, 12:43 AM