为什么BOOL是签名字符?

时间:2010-09-30 23:42:27

标签: objective-c

前几天,用户向我报告了一个错误,指出应该启用时禁用的工具栏项。验证码(为了您的利益而简化)看起来像:

- (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem {

    NSArray* someArray = /* arrray from somewhere*/

    return [someArray count];
}

我花了几分钟才意识到-count返回一个32位的unsigned int,而BOOL是一个8位的signed char。事实上,在这种情况下,someArray中有768个元素,这意味着较低的8位都是0.当int在返回时被转换为BOOL时,它会解析为NO,即使是人类希望答案是YES

我已经将我的代码更改为return [someArray count] > 0;但是,现在我很好奇为什么BOOL真的是一个签名的字符。这在某种程度上真的“更好”,那么它是一个int吗?

6 个答案:

答案 0 :(得分:12)

给出的答案(到目前为止)集中在为什么BOOL不是int。答案非常明确:char小于int,当Objective-C在80年代设计时,削减几个字节总是好的。

但你的问题似乎也在问:“为什么BOOL签名而不是签名?”为此,我们可以在/usr/include/objc/objc.h

中查看BOOL的类型定义
typedef signed char     BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.

所以有一个答案:Objective-C设计者不希望将typedef BOOL设置为char,因为在某些系统上,在某些编译器下(并记住Objective-C早于ANSI C,因此C编译器不同),一个char已签署,有些未签名。设计人员希望@encode(BOOL)跨平台返回一致的值,因此它们包含了typedef中的签名。

但这仍然引出了一个问题:为什么签名而不是签名?我没有明确的答案;我想,原因是他们不得不选择其中一个,并决定选择签名。如果我不得不进一步推测,我会说这是因为默认情况下会对符号进行签名(也就是说,如果它们不包含签名限定符)。

答案 1 :(得分:4)

回归到更简单的时间。

当CPU自然使用8位类型时很少创建BOOL类型,很少填充到16位或32位。然而,内存稀少,将1位填充到4个字节实际上会占用大量额外的内存。

请注意,BOOL可能早于C ++的_bool已经有一段时间了(iirc--它们的年龄可能大致相同。当NeXT选择Objective-C时,C ++的流行程度大致相同。)。

答案 2 :(得分:2)

一个明显的答案是它小了四倍(在典型的32位和64位架构上),并且没有任何对齐要求。

答案 3 :(得分:1)

布尔值仅需要一个位(0或1),但标准系统将字节作为最小单位处理。 bool表示为8位的字节,比32位整数小4倍,因此字节超过整数的动机。

答案 4 :(得分:1)

Bool可以节省一些空间并将值约束为0或1.这是一个较小的类型,原因与你可以使用浮点数超过一个,或者一个短的超长。只是空间问题。

这就是为什么明确你的转换是一个好主意,并且在布尔值的情况下,在两个相同类型之间执行实际逻辑比较以净​​化实际的bool而不是截断值。

答案 5 :(得分:0)

它更小,这一切都是真的。