When does Objective-C implicitly cast to BOOL?

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 to convert NSData to byte array in iPhone?
  • ‘CGFloat’ is not convertible to ‘UInt8' and other CGFloat issues with Swift and Xcode 6 beta 4
  • Fast method to cast to ?
  • how can i pass an int value through a selector method?
  • How do you convert a UnsafeMutablePointer<Void> to UInt8?
  • How can I convert an array to a tuple?
  • 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.

    2 Solutions Collect From Internet About “When does Objective-C implicitly cast to BOOL?”

    When does Objective-C implicitly cast to BOOL?

    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 as int.

    // Does this break when foo is 'dangerous'?`
    self.titleLabel.hidden = foo ? YES : NO;
    

    No, it doesn’t. (expr) when used as a “boolean” expression, is equivalent to (expr != 0). No risks here.

    // I'm pretty sure it breaks now
    self.titleLabel.hidden = ((BOOL)foo) ? YES : NO;
    

    Now this can break, since BOOL is just typedeffed to signed char, which is 8 bit on iOS. Thus, if foo, 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’t nil, this will incorrectly report false. You don’t want to do this superfluous, ugly and dangerous cast. If you want to be more explicit, write

    var = (obj != nil) ? valueOne : valueTwo;
    

    instead.

    There’s no casting in your first two samples. Writing if(expr) is equal to writing if(expr == 0).

    Your third example might indeed break in some cases, as described in the article you refer to.