Link to home
Start Free TrialLog in
Avatar of Laminamia063099
Laminamia063099

asked on

What is this syntax?

typedef struct
     {
     unsigned int fAdvise:1 ;  //what is this syntax with the ":1"
     unsigned int fDeferUpd:1 ;  //here too
     unsigned int fAckReq:1 ;   //and here
     unsigned int dummy:13 ;   //and here ":13"
     long         lPopPrev ;
     }
     POPADVISE ;

What does the syntax above with the semicolon mean?
A good explanation please (it may be simple, I just haven't seen it before :)

Laminamia
ASKER CERTIFIED SOLUTION
Avatar of Iexpert
Iexpert

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Laminamia063099
Laminamia063099

ASKER

So, the bitfield states how many bits are to be allocated for that field of the structure?  

Thus, lDummy has 13 bits, and fDeferUpd has 1 bit?

(I'm modifying some code, and for this reason I came across this syntax.  Thanks for the note about it's low portability).
It looks like whoever wrote this structure was trying to use dummy to align the variable lPopPrev on a word boundry (1+1+1+13 = 16).  You may find what follows to be easier to work with, and it takes the same amount of memory.  Use the #defines with the variable theFlag to keep track of what you need.

#define  fAdvise    0x0001
#define  fDeferUpd  0x0002
#define  fAckReq    0x0004

typedef struct
  {
  int theFlag;
  long         lPopPrev ;
  } POPADVISE ;
>>marcjb
How would you use those defines in the case you state?
If you want to set a condition, use OR.
If you want to test a condition, use AND.

For example:

To set the variable theFlag to fAckReq

theFlag |= fAckReq;
/* Same as  theFlag = theFlag | fAckReq; */

This has the effect of turing on the bit that represents fAckReq, and not changing the other bits.

To test, use AND.

if (1 == (theFlag & fAckReq)) /* Don't really need == 1 */
    THEN THE FLAG IS SET

You can now set or test any of the conditions without effecting any of the other bits.  Also, you can have as many conditions as there are bits in the variable.  Assuming the int is 16 bits, that is 16 conditions.

#define  COND1  0x0001
#define  COND2  0x0002
#define  COND3  0x0004
#define  COND4  0x0008
#define  COND5  0x0010
#define  COND6  0x0020
and so on ...

#define  COND1  0x0001
#define  COND2  0x0002
#define  COND3  0x0004
#define  COND4  0x0008
#define  COND5  0x0010
#define  COND6  0x0020

Why do the conditions go doubling in offset?  If it is a bit-by-bit check, why not:

#define  COND1  0x0001
#define  COND2  0x0002
#define  COND3  0x0003
#define  COND4  0x0004
#define  COND5  0x0005
#define  COND6  0x0006
...
#define  COND16 0x0010
 HEX          Binary
0x0001      0000000000000001
0x0002      0000000000000010
0x0004      0000000000000100
0x0008      0000000000001000
0x0010      0000000000010000
Note how only one bit is set.

If you use
0x0003      0000000000000011  <- Two bits are set!
same with
0x0005      0000000000000101

You are simply using the powers of 2 (doubling, like you said), because that is the way the bits are stored.
I understand hex representation, just was lost in this case.  Now I understand why they are doubled, to preserve all other bits when changing one.  

Also, how do the & AND and the | OR operators work.  I understand logic, but how does:

myFlag = myFlag | COND1;

change the first bit in this integer to 1?

let myFlag = 0
let COND1 be defined as 0x0001

myFlag = myFlag | COND1;
myFlag =  0x0000000000000000
        | 0x0000000000000001
          ------------------
          0x0000000000000001

So, myFlag now has bit one set.

As another example, assume myFlag = 4

myFlag = 0x0000000000000100

Now, let's OR it with COND1

myFlag =  0x0000000000000100
        | 0x0000000000000001
          ------------------
          0x0000000000000101

myFlag now equals 5 (0x0005), which means two of the bits are set.

If you now tested to see if bit 3 was set, you would get the following

if ( myFlag & COND3 )
 WHICH IS
if (  0x0000000000000101
    & 0x0000000000000100 )
    ---------------------
      0x0000000000000100
 This is not equal to zero, so it passes the if clause.
 See below about a mistake I made earlier when describing &


*****
I made one mistake earlier when describing the & function.

if (1 == (theFlag & fAckReq)) /* Don't really need == 1 */
  THIS IS NOT CORRECT

SHOULD BE
if (theFlag & fAckReq)
 OR
if ((theFlag & fAckReq) > 0)
 OR
if ((theFlag & fAckReq) != 0)
It was incorrect because what you said "== 1".  It could equal any value (in this case a power of 2) not equal to zero to be true.  I completely understand it now.  I don't know why it took me so long to see where you where coming from.  

Thanks a lot for your help.  I would like to give you some points, but lexpert answered my question that i did ask and I'm at zero points right now.  How can I repay you?
Don't worry about it.  Just glad to help out :)  Good luck,
marcjb