1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

Question about BOOL and style? Kochan 2.0 page 198

Discussion in 'Mac Programming' started by mdeh, Jan 18, 2009.

  1. macrumors 6502

    if ([Square isSubclassOfClass: [Rectangle class]] == YES);

    In the definition of "isSubclassOfClass" the return type is BOOL. BOOL is defined as a signed char.
    Now, if NO is 0, and YES **could** be anything but 0, would it not be better??? to have the comparison be to "!= 0" ?
    Thanks in advance.
  2. macrumors 6502a

    You don't even have to bother with the comparison.
    BOOL succes = YES or NO;
    If (succes)
     dosomething when yes
     sosomethingelse when no
    If (!succes)
     dosomething when no
     sosomethingelse when yes
    If ([afunction returnsBOOL])
     dosomething when yes
     sosomethingelse when no
  3. macrumors 65816


    The issue is readability and having YES or NO improves this. And like MrFusion says you don't have to always type == NO etc.
  4. macrumors regular

    Yes, it is a readability issue, but there's a little more to it than that. You should be aware that YES is defined in a system header file as 1. So if you write a method that returns a BOOL value, and you return a nonzero value to indicate "yes" or "true", then an expression such as

    if ( [myObject myMethod] == YES )
    will not work unless the method just happens to return 1.

    That means if you write a BOOL method, you should return YES for true and NO for false so that expressions such as the one shown will work. On the flip side, if you're invoking a method you didn't write, it's safer, though less readable, to test for truth without the explicit comparison to YES. That's in case the coder of the BOOL method returns a nonzero value for true. It's a little bit of a mess, as you can see. The documentation for the BOOL method should indicate the values the method returns, and that can serve as your guide.


    Steve Kochan
  5. macrumors 68040


    Not that my opinion is more valid than anyone else posting, but i thought i'd add it on this one. The failure of C to include a boolean type, and force only that type to be used in a conditional is a serious flaw. It's not the end of the world, people obviously get by without it, but it can lead to some real sloppiness and some serious errors.

    The BOOL typedef that's used in Objective-C is nice, TRUE and FALSE are #defined to 0 and 1 on a lot of systems as well. This sort of helps with readability, but doesn't address the real problem.

    For example:
    if(x = y) {
    This will be true as long as y is non-zero. In general, the intent is to use == to evaluate equivalence, not = for assignment, but an assignment expression evaluates to its second operand so you can do things like:
    x = y = z = 3;
    It also leads to people using if statements to check for nullity since a null pointer is equal to 0, etc. This seems pretty sloppy to me, because in english you want to ask "Is this pointer (non-)null?" not "Is this pointer?". While computer science has strong ties to logic and philosophy, the latter doesn't really make sense in this context. For this reason i would prefer that a logical operator be used in cases like this, so you say:
    if(myPtr != null) {
    f(myPtr != nil) {
    so what you're checking for is explicit.

    In this magical world where C supports a real boolean that must be used in an if statement, if you had a function that returned a boolean type, it would be perfectly correct (and readable, in my opinion if the function was named nicely) to just check its return value. In this imperfect world of typedef'd BOOLs, usw. we're stuck with the debate at hand, and some very difficult to read code out there.

    One workaround for the issue Steve mentioned (possibility of an external function that returns a BOOL not returning 1/YES for "truth") would be to only check against NO. This would either require you to always switch the if and else portion of your control structure, or check if things are != to NO instead of == to YES. It's ugly, but it would be "safer" than just using == YES for the reasons Steve mentioned.

    This doesn't really lead anywhere, but I thought i'd chime in because of some of the horrors i've come across (and assuredly I've written) that depend on this strange behavior. I understand on a lot of microarchitectures there's a JNE or JEQ sort of instruction that only checks against 0, which makes mapping easy... but a little more work in this area originally would have gone a long way in my opinion.

  6. macrumors 6502

    Could you elaborate slightly on this. Are you saying there is **NO** boolean type in C. If that is true, I do not follow the second part of the sentence.

    I **thought** that in plain old C, the value ZERO represented FALSE, and anything but ZERO represents True. Then in Obj-C, there seem to be 2 boolean values, _Bool and BOOL. Other than the definitions of YES and NO being 1 and 0 things get fuzzy!!! Perhaps, if you are so inclined, you or Steve might be able to put this all in perspective.
  7. macrumors regular

    There is a boolean type in C. However, it was added to the language a little late in the game (as part of what's known as the ANSI C99 standard). The type is _Bool, and it is a built-in data type. Only the values true and false can be assigned to a _Bool variable.

    On the other hand, BOOL is not a built-in type, it's a typedef defined in a system header file. It was added to the Objective-C language before the _Bool type existed in C. You can assign any value to a BOOL variable; however, the convention is to assign it just the values YES or NO (which are macros defined in a system header file).

    Because of this history (and the fact that it took a while for ANSI C 99 compilers to be developed), boolean methods in the frameworks have been declared to return BOOL values and not _Bool values.

    Hope this helps.


    Steve Kochan
  8. macrumors 68040


    There is(well, was originally) no boolean type in C. What i meant was that it would be great if there WAS a boolean type originally, and an expression that evaluates to that type were the ONLY thing that you could put in an if, the condition of a for, etc. I realize the ambiguity now. My intention was "The failure of C to include a boolean type which would be the only type that could be used in a conditional...". Hopefully that's clearer. Blasted english.

    Right, 0 is a negative condition, any non-zero value is a positive condition when evaluated in a conditional. Any sort of bool, boolean. BOOL, _bool, _booly, _mybool, etc.(except _Bool) in C is going to be typedef'd to something else. In Objective-C, it's in objc.h:
    typedef signed char             BOOL;
    #define YES             (BOOL)1
    #define NO              (BOOL)0
    #define nil 0           /* id of Nil instance */
    I included a few other items of interest in that header file. What this all adds up to is a (respectable) effort to make a boolean/logical kind of thing that is usable in place of something built-in in the language. The real issue is "responsible use" of what is available. It's easier to write ugly C than pretty C, but with some extra work it's doable, and people that have to maintain your code won't hate you. This pretty much all applies to Objective-C, too, since it has such inexorable ties to C, being that all C is Objective-C.


    EDIT: You and Steve mentioned the _Bool type. Unfortunately C99 is not widely used, even if compilers' support for it is improving. Even with this available you don't HAVE to use something that evaluates to _Bool as your condition in a conditional, and programers don't need to use it.

    EDIT 2: also, listen to Steve. He's the published author, I'm just a guy on the Internet. =)
  9. macrumors G4

    Actually the "== YES" part is borderline wrong What you have written is code that one day might not work if the funtion returned (say) 12 rather than one. It is perfectly OK to return 12 is "true" but your comparison would not longer work as written.

    One more thing. When ever you do have an == be sure and lplace the constant on the left side. This makes it clear it is NOT an asignment and also fails to compile if you leave off one of the two equal signs, a common error.

    I don't know how many times I've typo'd and writen "if(foobar=2)..." Man that is hard to find because it looks write. But 2=foobar would not compile.

    In the end it is best to say either "if( foobar )..." or "if( !foobar )" This is much more clear and work even if foobar() returns 12 to indicate true.
  10. macrumors regular

    Well, this is not a black and white issue, but I don't agree with you. :). As I stated, if a method is defined to return a value of type BOOL, then it must return a value of either YES or NO; otherwise it has not been properly coded. The unfortunate part is that programmers may not adhere to that convention. As I mentioned at the end of my previous post, the documentation for the method should describe the values returned (e.g. returns YES if the strings match, NO if they do not). And you can be sure that any BOOL methods in Apple's frameworks will return either YES or NO.

    For example. from Apple's NSFileManager documentation:

    - (BOOL)isWritableFileAtPath: (NSString *) path



    A file path.

    Return Value

    YES if the invoking object appears able to write to the file specified in path, otherwise NO. If the file at path does not exist, this method returns NO.


    By the way, to all who participated here, great discussion! And Lee1210, don't sell yourself short. Your opinion is certainly just as valid as mine and provoked an excellent discussion.


    Steve Kochan
  11. macrumors 6502

    It depends on what you think the "if" statement does. If you try to post-instill boolean awareness into C, you'd say something like "the if-statement executes the following block or statement if its argument evaluates to 'true'."

    But there is no notion of "true" in C, just like you said. So if you teach people that the if-statement "executes the following block or statement if its argument evaluates to nonzero", there is no problem at all. It is widely accepted C idiom to test for non-nillness of a pointer by doing "if (pointer) ...", and the confusion only arises when you think there's any boolean logic involved...

    Just the opinion of another published author, albeit less so than Steve :)

Share This Page