In C how do I "reverse" this operator |=
I'm new to programming in C and I have the following situation where I know what needs to be done, I'm just not sure of the right way to do. I'll try to keep it as simple as possible, and please let me know if I'm not providing enough info.
There's a .h file with this line:
#define NS_CONN_ENTITYTOOLARGE 0x2000
Then in the C code we have the following flag being set:
connPtr->flags |= NS_CONN_ENTITYTOOLARGE;
Then later on this test:
if (connPtr->flags & NS_CONN_ENTITYTOOLARGE) {
}
Now what I want to do is basically "undo" the flag NS_CONN_ENTITYTOOLARGE
. After some Googling I discovered that |=
is a "bitwise OR", but I don't feel a lot more enlightened after learning that. Do I need to do a bitwise XOR, a NOT or what?
Here are all the possible values for flags that I can find in the header file.
#define NS_CONN_CLOSED 0x1
#define NS_CONN_SKIPHDRS 0x2
#define NS_CONN_SKIPBODY 0x4
#define NS_CONN_READHDRS 0x8
#define NS_CONN_SENTHDRS 0x10
#def开发者_Python百科ine NS_CONN_KEEPALIVE 0x20
#define NS_CONN_WRITE_ENCODED 0x40
#define NS_CONN_FILECONTENT 0x80
#define NS_CONN_RUNNING 0x100
#define NS_CONN_OVERFLOW 0x200
#define NS_CONN_TIMEOUT 0x400
#define NS_CONN_GZIP 0x800
#define NS_CONN_CHUNK 0x1000
#define NS_CONN_ENTITYTOOLARGE 0x2000
You cannot reverse an OR to the previous value. Information is lost, consider this truth table:
A|B|OR
------
0|0|0
0|1|1
1|0|1
1|1|1
As you can see, information is lost because there are no distinct values for when A were 0 or 1.
What you want to know is how to remove a flag. This can be done by AND'ing with the inverse of the flag:
connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;
connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;
This doesn't exactly "undo" |=
because it may have been a no-op for some or all of the bits in NS_CONN_ENTITYTOOLARGE
, if they were already in the variable. In these case, those bits will be cleared too regardless of whether they were there in the first place.
A XOR:
connPtr->flags ^= NS_CONN_ENTITYTOOLARGE
Of course, that's considering (say):
flags
=01001101
NS_CONN
=00010000
Example:
flags |= NS_CONN;
OR 01001101
00010000
------------
01011101
And then:
flags ^= NS_CONN
XOR 01011101
00010000
-------------
01001101 (== original flags)
You need to do a bitwise and with the inverse of the flag:
connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;
Every bit of ~NS_CONN_ENTITYTOOLARGE
is 1
except for the bit that it represents.
Thus, every other bit of the value gets AND
ed with 1
, which does nothing.
You can't undo it per se - after the operation, connPtr->flags
will have a 1 bit in all positions where NS_CONN_ENTITYTOOLARGE
had a 1 bit (which is only one position in this case), and it is impossible to know what the original bit values there unless you have actually stored the original value of connPtr->flags
somewhere. If you are interested in turning changing the bit position(s) to 0 (which may not have been the original bit value), you can do as the other posts here say.
To remove the flag, you use AND:
connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;
This will take all the bits in the flags except NS_CONN_ENTITYTOOLARGE.
You want to use connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE
where &
is AND and ~
is NOT.
精彩评论