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
{
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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 ;
#define fAdvise 0x0001
#define fDeferUpd 0x0002
#define fAckReq 0x0004
typedef struct
{
int theFlag;
long lPopPrev ;
} POPADVISE ;
ASKER
>>marcjb
How would you use those defines in the case you state?
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 ...
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 ...
ASKER
#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.
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.
ASKER
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?
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)
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)
ASKER
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?
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
marcjb
ASKER
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).