在 Objective-C 中不使用 _Bool 的原因是什么?

发布于 2024-10-28 16:32:23 字数 1433 浏览 4 评论 0原文

从 C99 开始,C 现在有了一个正确的布尔类型,_Bool。 Objective-C 作为 C 的严格超集,继承了这一点,但是当它在 20 世纪 80 年代创建时,还没有 C 布尔类型,因此 Objective-C 将 BOOL 定义为 signed char

所有 Cocoa 都使用 BOOL,就像我见过的所有非 NeXT/Apple Cocoa 代码一样。显然,为了与现有协议兼容(例如,来自 NSApplicationDelegate-applicationShouldTerminateAfterLastWindowClosed:),如果没有其他原因而不是避免警告,最好匹配已声明的类型。

出于清洁/可读性的目的,stdbool.hbool 定义为 _Bool 的同义词,因此我们这些不希望在其中出现不必要的下划线的人我们的代码可以使用它。

其他三个有用的注释:

  • @encode(_Bool) 计算结果为 "B"。 (对于 signed char@encode(BOOL) 计算结果为 "c"。)
  • sizeof(_Bool) 计算结果到 1,根据 C99 的定义,_Bool 仅具有容纳其两个可能值所需的大小。 (编辑:实际上,该标准只说它必须“足够大”才能容纳这两个值;它没有设置上限,事实上,Mac OS 32 位 PowerPC 上的 X 将其定义为 4 个字节。 大小差异是在可能的 BOOL-vs.-bool 兼容性问题下归档的另一件事。
  • )请注意,_Bool 唯一的两个可能值是 1 和 0。任何其他值都会在赋值时转换为其中之一,就像您进行了双重否定一样 (!!)或针对 0 测试不等式(!= 0)。获得具有其他值的 _Bool 的唯一方法是常见的魔法:指针别名和联合。

有什么理由不在新代码中使用 _Bool/bool 吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别闹i 2024-11-04 16:32:23

我认为你们几乎都回答了自己的问题 - 在新的 Cocoa 代码中不使用 _Bool 的原因是,直到苹果将其框架更改为使用 _Bool (或更可能是 stdbool.h 中定义的 bool ),您就会打破通过使用 _Bool 或 bool 来实现约定和可能的兼容性(至少没有 hack)。虽然我现在只专注于 Cocoa 编程几年,但我敢打赌,如果 Apple 完全合并了 _Bool,他们可能会简单地重新定义 BOOL 宏以在幕后使用新类型,以避免未知的编辑他们的框架及其文档。

话虽这么说,(让我先声明一下,我还没有将 C 代码与 Objective-C 混合在一起,并且不知道这样做的约定),您有一个更好的情况来在其中使用新的 _Bool C 函数,可能需要注意的是,它仅在内部使用,并且不要求 Objective-C 方法传入 _Bool,只是为了避免未来程序员的困惑。当然,您还必须适应始终需要 C99 编译,人们可能仍然有理由避免这样做。考虑到 YES 是 1 的宏,NO 是 0 的宏,要求较新版本的 C 来获取另一个仅使用 1 或 0 的字符大小的值似乎没有太大好处。

老实说,当它出现时归根结底,您可以通过足够的黑客技术或对可重用性进行限制来解决任何这些原因,但最终的理由是它(目前)不是 Cocoa/Objective-C 俚语的一部分,并且它的好处可能不会超过可读性的损失和/或其他不太了解 _Bool 的程序员阅读您的代码时增加的混乱。

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.

べ映画 2024-11-04 16:32:23

对于 Objective-C,只需使用 BOOL 数据类型...

对于 C,我推荐以下宏,它也适用于 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

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
你对谁都笑 2024-11-04 16:32:23

我同意@pst。 Objective-C 并没有隐藏 C,但它仍然是 C 之上的一层。这意味着 Objective-C 只是不同的层。

我认为这是一个关于语言上下文的问题。虽然并不总是很清楚,但我们知道 C 上下文和 Objective-C 上下文。就像AmericanAmericano 一样。它们本质上是相同的含义,但根据上下文不同,并且可能因上下文而略有不同。当这些小细节积累起来时,它可以为读者提供一些明显的信息。它将有助于提高代码的可读性。

我相信你应该知道可读性的重要性。如果可读性不重要,我们不需要使用任何制表符或空格。 :)

作为另一个例子,有 nilNULLstrlen()-[NSString length]BOOL 可以说“我是 Objective-C 代码。” 强烈,而 _Bool 则不能。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文