Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does !! mean in objective-c syntax?

Tags:

objective-c

I found some code similar to the following:

BOOL hasValue_:1;

- (BOOL) hasValue {
    return !!hasValue_;
}

- (void) setHasValue:(BOOL) value {
    hasValue_ = !!value;
}

I'm wondering why the double exclamation points are necessary? Are we not already passing BOOL to the method and returning BOOL? Is BOOL really a typedef for an int?

Thanks!

EDIT
Thanks for all of the responses thus far. I understand that using !! with other data types effectively performs some typecasting to a boolean result. However, in the example above, I'm strictly working with BOOL already.

EDIT
If I'm working with a BOOL already, why is it necessary to normalize it to a 0 for false and 1 for true? Doesn't a BOOL guarantee that it is false for 0 and true for everything else?

like image 818
Tim Reddy Avatar asked Apr 08 '11 13:04

Tim Reddy


4 Answers

I'm wondering why the double exclamation points are necessary?

BOOL is a signed char, or a char posing as a boolean type via typedef. It will happily represent any integer in the range [SCHAR_MIN...SCHAR_MAX]. The double exclamation point applies a boolean NOT operation twice, which effectively converts the original value to an int of 0 or 1, narrowing the value to the range of boolean.

But there's a twist: BOOL hasValue_:1; declares a single-bit bitfield representation. It can represent two values. return !!hasValue_; is not needed. However, it is needed to correctly narrow when going from signed char (BOOL) to one bit.

Are we not already passing BOOL to the method and returning BOOL?

Nope. It's a signed char. !!value reduces input values to YES or NO.

If I'm working with a BOOL already, why is it necessary to normalize it to a 0 for false and 1 for true?

Doesn't a BOOL guarantee that it is false for 0 and true for everything else?

BOOL is a signed char. A typedef of signed char does not make this guarantee.

C99 (which has been available for you to use for many years when targeting osx or ios) has a more useful boolean type representation (bool). Unfortunately, BOOL remains in regular use in objc for historical reasons. Personally, I use BOOL only when necessary (e.g. overriding).

like image 175
justin Avatar answered Nov 14 '22 18:11

justin


I'm not 100% certain about objective C, but in other languages, it's two boolean operators next to each other. It's typically used to ensure that falsy or trusy statements are converted to proper booleans (e.g. true or false). Since objective C is derived from C, there's a good chance that this is also what it's used for.

like image 28
Johnny Oshika Avatar answered Nov 14 '22 19:11

Johnny Oshika


Looking at this question, BOOL is a typedef for signed char. This means that it could have values aside from 0 or 1 (on all modern systems I'm familiar with, it can have values from -128 to 127). It shouldn't, but I wouldn't like to count on a BOOL always having values 0 or 1.

Therefore, it's desirable to have a way of normalizing it to 0 or 1. In C and the derived languages I'm familiar with, ! is the not operator, which takes a value and returns either 1 if the value is treated as false (in C, that would be numeric 0 or 0.0 or the null pointer constant for a pointer type), and 0 otherwise. !! is just ! applied twice, which yields 0 for an initially false value and 1 for an initially true value.

like image 26
David Thornley Avatar answered Nov 14 '22 19:11

David Thornley


The double exclamation points is a way to cast an integer to a BOOL, where 1 (and ANY other value != 0) is true and 0 is false. Also, what you are writing is C and not objective-c. Your code will work in a C++ environment as well, since it is also a derivative of c.

like image 41
David Avatar answered Nov 14 '22 18:11

David