19

Since C99, C now has a proper Boolean type, _Bool. Objective-C, as a strict superset of C, inherits this, but when it was created back in the 1980s, there was no C Boolean type, so Objective-C defined BOOL as signed char.

All of Cocoa uses BOOL, as does all non-NeXT/Apple Cocoa code that I've seen. Obviously, for compatibility with existing protocols (e.g., -applicationShouldTerminateAfterLastWindowClosed: from NSApplicationDelegate), matching the already-declared type is preferable, if for no other reason than to avert a warning.

For cleanliness/readability purposes, stdbool.h defines bool as a synonym for _Bool, so those of us who don't want unnecessary underscores in our code can use that.

Three other useful notes:

  • @encode(_Bool) evaluates to "B". (@encode(BOOL) evaluates to "c", for signed char.)
  • sizeof(_Bool) evaluates to 1, which follows from C99's definition that _Bool is only as large as necessary to hold its two possible values. (Edit: Actually, the standard says only that it must be “large enough” to hold those two values; it does not place an upper bound, and, in fact, Mac OS X on 32-bit PowerPC defines it as 4 bytes. Size difference is another thing to file under possible BOOL-vs.-bool compatibility issues.)
  • On that note, the only two possible values of a _Bool are 1 and 0. Any other values are converted to one of these on assignment, as if you had done a double-negation (!!) or tested inequality against 0 (!= 0). The only ways to get a _Bool with some other value are the usual magicks: Pointer aliasing and unions.

Is there any reason not to use _Bool/bool in new code?

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • 3
    Objective-C isn't a 'strict superset of C' it is a 'a strict superset of a *particular* C' and is likely closely associated with the particular Objective-C version being targeted... anyway, ramble aside: Objective-C is also about conventions and for a particular environment / set of environments (as pointed out in the question), `BOOL` *is* part of that convention. I wouldn't rock the ship but have no "proper" justification (e.g. any incompatibilities?). –  Apr 02 '11 at 20:24
  • Also, `sizeof(t)` returns the number of chars, not the number of bits so ... I am confused with that statement. (Assuming 8 bits/char, that's far more than a boolean value requires). –  Apr 02 '11 at 20:25
  • 3
    It's a strict superset of whatever C you pick: C89, C99, or the GNU extensions thereof. To the extent that compiler-specific C extensions that aren't part of Objective-C are present, they will be whether you use (that compiler's) Objective-C or (that compiler's) plain C. And yes, it's the number of bytes (not necessarily octets); you can't have an object (by the C meaning of the term) smaller than a single byte. The closest you can get is structure members defined as some number of bits long, but even then, the implementation may/will round up as it sees fit. – Peter Hosey Apr 02 '11 at 21:40
  • I'm actually also very interested in seeing answers to this. Is there any clear justification besides the fact that Apple uses `BOOL`? – Itai Ferber Apr 02 '11 at 21:50
  • 5
    Why wouldn't the fact that Foundation, AppKit, and all the related framework APIs use BOOL be sufficient justification to do likewise? IMHO, one would need to justify *not* going along with the standard system APIs. – Sherm Pendley Apr 02 '11 at 23:12
  • @Sherm Pendley: One good reason I can see to prefer `_Bool` is the automatic conversion of any value to 1 or 0. Assigning a non-zero whose lowest byte is all zero will assign 0 to a `BOOL`, but assigning any non-zero value to a `_Bool` will assign 1. – Peter Hosey Apr 03 '11 at 00:13
  • @Peter - To each his own; I view that as a good reason to *avoid* _Bool. :-) Why waste unnecessary cycles on such conversions when any non-zero value will be evaluated as true anyway? Granted, the waste is miniscule, but still - I'd need more justification than that to avoid BOOL, even if the conversion were entirely cost-free. – Sherm Pendley Apr 03 '11 at 00:26
  • @Sherm Pendley: I'm not worried about the cycles; I worry more about the potential data loss. – Peter Hosey Apr 03 '11 at 00:46
  • 1
    @Peter - The potential data loss posed by writing something stupid like `if (aBOOL == 1)` is easily avoided by simply not writing stupid code. :-) ObjC's TRUE/FALSE/YES/NO constants are to be used only in assignments, never in conditional statements. – Sherm Pendley Apr 03 '11 at 01:00
  • @Peter - Also, please keep in mind that, as I said earlier, I'm speaking from the perspective of needing to justify breaking with the established Cocoa convention of using BOOL. If I'm writing portable, standard C (as I would for a model layer that's intended for use across a variety of platforms, for instance) I'd follow *that* convention and use _Bool. – Sherm Pendley Apr 03 '11 at 01:09
  • @Sherm Pendley: I'm not talking about `if (aBOOL == 1)`. That isn't data loss. I am specifically talking about the data loss I referred to in my earlier comment. – Peter Hosey Apr 03 '11 at 01:43
  • @Peter - Same deal - assign YES or TRUE instead of doing something stupid like `aBOOL = 1024`. If necessary, write it as `aBOOL = anInt ? YES : NO`. Seriously, I think you're **way** overstating the risks here. Stupid programmers will simply find another way to shoot themselves in the foot anyway. :-) – Sherm Pendley Apr 03 '11 at 01:47

3 Answers3

2

I think you all but answered your own question- the reason not to use _Bool in new Cocoa code is that, until Apple changes its frameworks over to using _Bool (or more probably, the bool defined in stdbool.h), you're breaking convention and possibly compatibility (at least without hacks) by using _Bool or bool. Although I've only been steeping in Cocoa programming for a couple years now, I'd bet that if Apple incorporates _Bool at all, they will probably simply redefine the BOOL macro to use the new type behind the scenes anyway, to avoid untold editing to their framework and its documentation.

That being said, (and let me preface this by disclaiming that I've yet to mix C code in with Objective-C and don't know the conventions for doing so), you have a much better case for using the new _Bool within C functions, probably with the caveat that it is only used internally and doesn't ask an Objective-C method to pass in a _Bool, just to avoid confusion for future programmers. You'd also of course have to be comfortable with always requiring C99 compilation, which people may still have reason to avoid. Considering YES is a macro for 1 and NO is a macro for 0, there doesn't seem to be much gain in requiring a newer version of C to get another char-sized value that only uses 1 or 0.

Honestly, when it comes down to it, you can get around any of these reasons with enough hackery or restrictions placed on reusability, but the end justification is that it's not (currently) part of the Cocoa/Objective-C slang, and its benefits probably won't outweigh the loss in readability and/or added confusion of other less-privy-to-_Bool programmers reading your code.

matthias
  • 2,419
  • 1
  • 18
  • 27
0

With Objective-C, just use the BOOL data-type...

For C, I recommend the following macros, that will also work with ANSI-C (C-89):

#ifndef __bool_true_false_are_defined
    #ifdef _Bool
        #define bool                        _Bool
    #else
        #define bool                        char
    #endif
    #define true                            1
    #define false                           0
    #define __bool_true_false_are_defined   1
#endif
Macmade
  • 52,708
  • 13
  • 106
  • 123
  • 3
    That doesn't answer the question, which is *why* I should use `BOOL` in preference to `_Bool` (when compatibility with an existing protocol isn't an issue). – Peter Hosey Apr 02 '11 at 20:09
  • 2
    Furthermore, this example is undefined behavior: identifiers beginning with two underscores (as well as an underscore followed by a capital letter) are reserved for use by the implementation. Defining them yourself is UB. You're allowed to define `bool`, `true`, and `flase`, but **only** if you *don't* include `` in your code. – Adam Rosenfield Apr 03 '11 at 01:33
  • 1
    __bool_true_false_are_defined are specified by the C standard, in stdbool, which is not available in C-89... This macro will allow you to use bool even in C-89. – Macmade Apr 03 '11 at 05:33
0

I agree with @pst. Objective-C doesn't hide C, but it's still a layer on top of C. This means Objective-C is simply different layer.

I think this is a problem about language context. It's not always clear, but we know kind of C-context and Objective-C context. Like American vs Americano. They're essentially same meaning but differentiate the context, and could be different a little by the contexts. And it can make some obvious information for reader when those little details are accumulated. It will help to increase code readability.

And I believe that you should know importance of readability. If readability is not important, we don't need to use any tabs or white-spaces. :)

As another examples, there are nil vs NULL, strlen() vs -[NSString length]. BOOL can say "I'm Objective-C code." strongly which _Bool can't.

eonil
  • 83,476
  • 81
  • 317
  • 516