When is Objective-C implicitly coerced to BOOL?

I am reading Mike Ash's Objective-C hooks page and now I am paranoid about implicitly mutable variables like id

to BOOL

.

Suppose I have a "dangerous" pointer with the least significant bits zeroed out, so casting it to BOOL

will result in NO

, even if it points to a valid object. Let's call this "dangerous" pointer foo

.

How do simple if statements work? Does the if statement cause a foo

value BOOL

when evaluating a condition? Or is it cast into a purely logical one?

if( foo )
{
  [myArray addObject:foo];
}

      

Does it work the same way in triple expressions?

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

      

Or will it be ternary only if I do this:

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

      

It seems to me that I am missing something basic about logical operations in C and how they relate to BOOL

. Please help me enlighten.

+3


source to share


2 answers


When is Objective-C implicitly cast into BOOL?

Never, because this phrase is semantically incorrect. The listing is, by definition, explicit. What you are asking for is called "implicit type conversion" (coercion - thanks Josh!).

Also, strictly speaking, conventions in Objective-C are not special: they inherit from C. Thus, expressions, when necessary to evaluate as boolean, are not treated as BOOL

, but how int

.

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

      

No, it is not. (expr)

when used as a "boolean" expression is equivalent (expr != 0)

. There are no risks here.



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

      

Now this might break as it is BOOL

just typed on signed char

, which is 8 bits in iOS. Thus, if foo

which is a (32-bit) pointer is truncated to 8 bits, and the bottom 8 bits of the pointer are zero, but the pointer itself was not nil

, it would incorrectly report false. You don't want to make that unnecessary, ugly and dangerous throw. If you want to be more explicit, write

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

      

instead.

+8


source


There are no castings in your first two samples. The if (expr) record is equal to the if (expr == 0) record.



In some cases, your third example might actually break, as described in the article you link to.

+1


source







All Articles