Sign in to follow this  

Qustion about bitwise-AND-assign

This topic is 4418 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know that
someBool &= someOtherBool;
is equivalent to
someBool = someBool & someOtherBool;
The question is, are they equivalent to
someBool = someBool && someOtherBool;
? It seems to me that they should be, since bools are implemented as a single bit - right? It would make my code look a lot prettier.

Share this post


Link to post
Share on other sites
Noooo! Bools are not a single bit. Usually they're the same size as a char. The actual size may be implementation-specific, I'm not sure about that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
Noooo! Bools are not a single bit. Usually they're the same size as a char. The actual size may be implementation-specific, I'm not sure about that.
That doesn't stop them only using a single bit. Whether they do or not, I'm not sure. *Starts hunting around in the C++ Standard*

EDIT: I couldn't find any guarantees about the storage of a bool; only that it is an integral type that you can do bitwise operations on. Still, I'd imagine that most compilers you tested it on would have both results equal.

Share this post


Link to post
Share on other sites
bools are not a single bit. I don't think it's defined how big they are actually. In VC2005 sizeof(bool) == 1.

Nevertheless using & instead of && *should* work since bools are guaranteed to convert to 0 or 1. I probably still wouldn't recommend it though.

Share this post


Link to post
Share on other sites
Cut it out with bitwise ops on bools. Here's why:


bool a, b, c; a = b & c;

What does this do? If you answered "ANDs b and c, and stores the result in a", you get no cookie. What it does: It generates an integer representation of b which is 1 if b is true and 0 if b is false. Then it generates an integer representation of c which is 1 if c is true and 0 if c is false. Then it takes the bitwise AND of the two integers. If the result is 0, a is assigned to be true. If the result is nonzero, a is assigned to be false.

So overall this happens to have the effect of logical AND. But don't use it like that, because that's not what's really happening.

Share this post


Link to post
Share on other sites
Quote:
Original post by TDragon
That doesn't stop them only using a single bit. Whether they do or not, I'm not sure. *Starts hunting around in the C++ Standard*

The sizeof bool cannot be smaller than the sizeof char. This is because types are required to be uniquely addressable, and char is defined as the smallest addressable type.

Share this post


Link to post
Share on other sites
Quote:
Original post by TDragon
Quote:
Original post by Red Ant
Noooo! Bools are not a single bit. Usually they're the same size as a char. The actual size may be implementation-specific, I'm not sure about that.
That doesn't stop them only using a single bit. Whether they do or not, I'm not sure. *Starts hunting around in the C++ Standard*


Okay, let's look at the following example:


// The code below assumes that sizeof( bool ) == sizeof( unsigned char ).
unsigned char nSomeChar = 8;
unsigned char nSomeOtherChar = 2;
bool bMyFirstBoolean& = *reinterpret_cast < bool* > ( &nSomeChar );
bool bMySecondBoolean& = *reinterpret_cast < bool* > ( &nSomeOtherChar );

// Bitwise AND of 8 and 2 ==> 0 ... which evaluates to false.
bool bMyResultingBoolean = bMyFirstBoolean & bMySecondBoolean;

// Logical AND of 8 and 2 (same as logical AND of true and true) ... evaluates to true.
bool bTheTrueResult = bMyFirstBoolean && bMySecondBoolean;



Unless I've got a serious flaw in my thinking.




Share this post


Link to post
Share on other sites
This is something that you could easily test, and you should have before asking.
Now the question is, did you actually try and figure it out?

Now, on to the question.
Even though it's not something people would normally do, it does actually work.

If you use code and check EVERY possible way things could be, then it will work EVERY time. Now, in this case that proof is simple since bool only has two values, true and false.

So, do something like this:


void main()
{
bool bFalse = false;
bool bTrue = true;
bool bTest1, bTest2, bTest3;

bTest1 = true;
bTest1 &= bTrue;

bTest2 = true;
bTest2 = bTest2 & bTrue;

bTest3 = true;
bTest3 = bTest3 && bTrue;

if( bTest1 == bTest2 && bTest1 == bTest3)
std::cout << "True" <<endl;
else
std::cout << "False" << endl;

bTest1 = false;
bTest1 &= bTrue;

bTest2 = false;
bTest2 = bTest2 & bTrue;

bTest3 = false;
bTest3 = bTest3 && bTrue;

if( bTest1 == bTest2 && bTest1 == bTest3)
std::cout << "True" <<endl;
else
std::cout << "False" << endl;

bTest1 = true;
bTest1 &= bFalse;

bTest2 = true;
bTest2 = bTest2 & bFalse;

bTest3 = true;
bTest3 = bTest3 && bFalse;

if( bTest1 == bTest2 && bTest1 == bTest3)
std::cout << "True" <<endl;
else
std::cout << "False" << endl;

bTest1 = false;
bTest1 &= bFalse;

bTest2 = false;
bTest2 = bTest2 & bFalse;

bTest3 = false;
bTest3 = bTest3 && bFalse;

if( bTest1 == bTest2 && bTest1 == bTest3)
std::cout << "True" <<endl;
else
std::cout << "False" << endl;
}




And then everything comes out great, then you are good to go.
In this case the output I got was:

True
True
True
True

So, it works. There ya go. Next time you can try thiskind of method before asking. Otherwise, if you can't figure it out this way, come on back.

- Bnty_Hntr

Share this post


Link to post
Share on other sites
We have a slight misunderstanding hinging on the use of the word "using". What I meant was, although a bool occupies a certain number of bits/bytes in memory, operations on it must not necessarily "use" or "depend on" all those bits.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bnty_Hntr
If you use code and check EVERY possible way things could be, then it will work EVERY time. Now, in this case that proof is simple since bool only has two values, true and false.
[...]

So, it works. There ya go. Next time you can try thiskind of method before asking. Otherwise, if you can't figure it out this way, come on back.


But I just gave an example where the result is not what you'd expect. Granted, it took a bit of malicious reinterpret_casting to make it not work, but at the end of the day bitwise operators and bools just don't mix very well.

Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
Quote:
Original post by Bnty_Hntr
If you use code and check EVERY possible way things could be, then it will work EVERY time. Now, in this case that proof is simple since bool only has two values, true and false.
[...]

So, it works. There ya go. Next time you can try thiskind of method before asking. Otherwise, if you can't figure it out this way, come on back.


But I just gave an example where the result is not what you'd expect. Granted, it took a bit of malicious reinterpret_casting to make it not work, but at the end of the day bitwise operators and bools just don't mix very well.


Apparently, if you are able to prove that in EVERY possible case, the answer is correct then it will always be correct. In my case, using straight bool values, I proved EVERY possible case and therefore it must be correct.

Now, if you want to mess around with reinterpret_casting then it isn't always true.
So, in the end, if you are working with ONLY bool values, and not casting back and forth (even though I have no idea why you would), the method should be fine. Although, I also don't know why using && would make any difference in code anyway.
I would prefer

someBool &= someOtherBool;

to

someBool = someBool && someOtherBool;

anyday.

Share this post


Link to post
Share on other sites
Quote:
Original post by TDragon
We have a slight misunderstanding hinging on the use of the word "using". What I meant was, although a bool occupies a certain number of bits/bytes in memory, operations on it must not necessarily "use" or "depend on" all those bits.

Ah, yes. Well, yes, all the implementations of bool I know of only use the lowest-order bit, and keep everything else 0. That simplifies conversion **TO** integer. As for conversion **FROM** integer, it's also convenient because many CPU architectures have opcodes which signal boolean results as 0 or 1. Of course, this may cause bad craziness if someone manages to put something other than 0 or 1 in the memory space of a bool.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bnty_Hntr
I would prefer

someBool &= someOtherBool;

to

someBool = someBool && someOtherBool;

anyday.


o rly? Tell me: What does dontQuitYet &= GetMessage(...); do? Hint: GetMessage is defined as BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax).

Share this post


Link to post
Share on other sites

for( char c = -128 ; c < 127 ; ++c )
{
bool *bo = (bool*)&c;
if( *bo )
cout << "true" << endl;
else
cout << "false" << endl;
}



outs a whole load of "true"'s and one "false". i assume the false is when it hits zero :)

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
outs a whole load of "true"'s and one "false". i assume the false is when it hits zero :)

On your particular version of your particular compiler, with your particular compilation settings, given the particular current phase of the moon and the current price of a cheeseburger in Laos. Such tests are not useful for determining general behavior.

Share this post


Link to post
Share on other sites
Well, I did in fact draw the logic table, and I tested it with my interpreter, and both of those gave me 'yes, they are equivalent.' So possibly my question was phrased a little badly; I should have asked, 'Is this true by guarantee, or is it a quirk of my compiler?'

Share this post


Link to post
Share on other sites
Apologies for any thread derailing that happened. The general consensus seems to be "quirk of the compiler" or, better, "don't rely on it".

EDIT: Okay, actually what you originally posted appears to be guaranteed true, but the intervening variations confused me. That seems to happen fairly often. Just pretend I never posted anything, 'kay? mkay.

Share this post


Link to post
Share on other sites
Quote:
Original post by King of Men
'Is this true by guarantee, or is it a quirk of my compiler?'

True by guarantee (in the very specific case you mentioned), but still evil. [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by DuFaceTheBass
Then use this:

someBool &&= someOtherBool;


You would think so, yes, but it doesn't seem to be allowed. At any rate, my compiler doesn't like it and I couldn't find it in the first list of C++ operators that I looked in.

Share this post


Link to post
Share on other sites
Quote:
Original post by King of Men
Quote:
Original post by DuFaceTheBass
Then use this:

someBool &&= someOtherBool;


You would think so, yes, but it doesn't seem to be allowed. At any rate, my compiler doesn't like it and I couldn't find it in the first list of C++ operators that I looked in.


DuFaceTheBass was just either being extremely sarcastic or extremely dense in saying that. Ignore it.

@Sneftel

Quote:
Original post by Sneftel
o rly? Tell me: What does dontQuitYet &= GetMessage(...); do? Hint: GetMessage is defined as BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax).


That technically evaluates to dontQuitYet = dontQuitYet & GetMessage(...)
Which, assuming GetMessage returns a bool, according to the logic we've been arguing is the same as dontQuitYet = dontQuitYet && GetMessage(...)

Share this post


Link to post
Share on other sites
Quote:
Original post by Bnty_Hntr
Which, assuming GetMessage returns a bool, according to the logic we've been arguing is the same as dontQuitYet = dontQuitYet && GetMessage(...)

Nope! It's way more complicated than that. [grin] BOOL != bool.

Share this post


Link to post
Share on other sites

This topic is 4418 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this