为什么BOOL是签名字符?

mbo*_*das 9 objective-c

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

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

    NSArray* someArray = /* arrray from somewhere*/

    return [someArray count];
}
Run Code Online (Sandbox Code Playgroud)

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

我已经改变了我的代码,return [someArray count] > 0;但现在我很好奇为什么BOOL真的是一个签名的char.这是真的"更好"在某种程度上它是一个int吗?

mip*_*adi 12

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

但是你的问题似乎也在问:"为什么BOOL签名而不是签名?" 为此,我们可以查看BOOL在typedef中的位置/usr/include/objc/objc.h:

typedef signed char     BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
Run Code Online (Sandbox Code Playgroud)

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

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


bbu*_*bum 5

回到更简单的时代。

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

请注意,BOOL可能比C ++的_bool早了一段时间(iirc,它们可能处于相同的年龄。当NeXT选择Objective-C时,C ++的流行程度差不多)。


oad*_*ams 0

它更小,仅此而已。