I got to talking with a coworker about some code that tested bitmasks:
Don’t do this; you are inviting pain, suffering, and head-scratching debugging.
I wrote about the wonderland of joy and kittens that is C arithmetic
but only in the abstract.
BOOL provide concrete examples that hit where it hurts.
Apple now recommend
NSUInteger for your option bits.
But we keep holding on for dear life to
BOOL, which is a
That means our bitmasks and our booleans differ
in both signedness and width.
Have a look-see: Given this seemingly innocuous arrangement:
1 2 3 4
This naïve flag test assigns zero:
while this works just fine, and gives a non-zero result, as expected:
_Bool Is So Swell
The reason is that assignments to
bool expands to when you include
are effectively run through a double-bang, as if you’d written this:
Added after initial publication. Thanks, Mark!
Running iOS on arm64? Is today ever your lucky day!
Unlike every other Apple platform, arm64 iOS (and the 64-bit simulator)
BOOL to be
bool. You get sanity for free.
Just don’t forget to test on a non-arm64 platform if you plan to release to a non-arm64 platform, because it’s still the wild west out there.
The double-bang trick coerces the value to be either 0 or 1:
- The first bang inverts its logical value, so if it was non-zero (true) it’s now 0 (false), and if it was zero (false), it’s now 1 (true).
- The second bang reverses that, and NOT NOT TRUE is just TRUE, so we’re logically back where we started, only now with a tidy, known arithmetic value representing that logical value.
If you apply this trick, then the assignment to
BOOL plays out as you’d hope:
You might also see this written like so:
Since the result of the bit-and is either
== test results in either
There’s Always a Moral
The moral is:
!!, and beware the wicked type conversions.
Get the Gist
You’ll find some ready-to-compile, comment-full sample code demonstrating these issues over in this gist.
BOOL might be
NO themselves are a bit more than just that now,
to support integer literals. That’s neither here nor there.
EDIT: Fixed 0 for 1 typo graciously pointed out by Mike Cohen.