I read Mike Ash’s Objective-C pitfalls page, and now I’m paranoid about implicitly casting variables of type id to BOOL.
Assume I have a ‘dangerous’ pointer with the lower bits zeroed out, so that casting it to a BOOL would produce NO even though it points to a valid object. Let’s call this ‘dangerous’ pointer foo.
How do simple if statements work?
Does the if statement cast foo to a BOOL when it evaluates the condition? Or does it cast to a pure boolean?
if( foo )
{
[myArray addObject:foo];
}
Does it work the same way in ternary expressions?
// Does this break when foo is 'dangerous'?
self.titleLabel.hidden = foo ? YES : NO ;
Or will the ternary only break if I do this:
// I'm pretty sure it breaks now
self.titleLabel.hidden = ((BOOL)foo) ? YES : NO ;
I feel like I’m missing something basic about logical operations in C, and how they relate to BOOL. Please help enlighten me.
Never, since this phrase is semantically incorrect. A cast is, by definition, explicit. What you’re asking about is called an “implicit type conversion” (coercion – thanks, Josh!).
Also, strictly speaking, the conditionals in Objective-C are not special: they’re inherited from C. So expressions, when needed to evaluated as booleans, aren’t treated as
BOOL, but asint.No, it doesn’t.
(expr)when used as a “boolean” expression, is equivalent to(expr != 0). No risks here.Now this can break, since
BOOLis just typedeffed tosigned char, which is 8 bit on iOS. Thus, iffoo, which is a (32-bit) pointer, gets truncated to 8 bits, and the lower 8 bits of the pointer were all zero, but the pointer itself wasn’tnil, this will incorrectly report false. You don’t want to do this superfluous, ugly and dangerous cast. If you want to be more explicit, writeinstead.