当我使用BOOL
代替32位时,我得到:
BOOL b1=8960; //b1 == NO
bool b2=8960; //b2 == true
但对于64位,我得到:
BOOL b1=8960; //b1 == YES
bool b2=8960; //b2 == true
有关BOOL
从32位到64位的变化是什么?
答案 0 :(得分:89)
@TimBodeit是对的,但它没有解释为什么......
BOOL b1=8960; //b1 == NO
...评估32位iOS上的NO
以及为什么它在64位iOS上评估为YES
。让我们从同一个开始。
ObjC BOOL定义
#if (TARGET_OS_IPHONE && __LP64__) || (__ARM_ARCH_7K__ >= 2)
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif
对于64位iOS或ARMv7k(手表),它被定义为bool
,其余为signed char
。
ObjC BOOL YES和NO
阅读Objective-C Literals,您可以在这里找到:
以前,
BOOL
类型只是signed char
的typedef,而且YES
和NO
是扩展为(BOOL)1
和(BOOL)0
的宏 分别。为了支持@YES
和@NO
表达式,这些宏是 现在使用<objc/objc.h>
中的新语言关键字定义:
#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
编译器隐式将
__objc_yes
和__objc_no
转换为(BOOL)1
和(BOOL)0
。关键字用于消除BOOL和整数的歧义 文字。
布尔定义
bool
是stdbool.h
中定义的宏,它扩展为_Bool
,这是C99中引入的布尔类型。它可以存储两个值0
或1
。没有其他的。更准确地说,stdbool.h
定义了四个要使用的宏:
/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool, bool, false, true as a GNU extension. */
#define _Bool bool
#define bool bool
#define false false
#define true true
#endif
#define __bool_true_false_are_defined 1
<强> _Bool 强>
_Bool
是在C99中引入的,它可以包含值0
或1
。重要的是:
当某个值降级为
_Bool
时,如果值为0
,则结果为0
等于1
,否则为BOOL
。
现在我们知道这个混乱的来源,我们可以更好地了解正在发生的事情。
64位iOS || ARMv7k 强>
bool
- &gt; _Bool
- &gt; 0
(值1
或8960
)
将_Bool
降级为1
会产生0
,因为该值不等于BOOL
。请参阅( _Bool 部分)。
32位iOS
signed char
- &gt; -128
(值127
至int
)。
如果您要将-128
值(127
至signed char
)存储为int
,则每个C99 6.3.1.3的值不变。否则它是实现定义(C99引用):
否则,新类型已签名且无法表示该值 在里面;结果是实现定义的还是 实现定义的信号被提出。
这意味着clang可以决定。为了缩短它,使用默认设置,clang将其包裹起来(signed char
- &gt; -129
):
127
变为-130
,126
变为-131
,125
变为128
,反方向:
-128
变为129
,-127
变为130
,-126
变为signed char
,但由于-128
可以存储127
到0
范围内的值,因此它也可以存储256
。例如,int
(0
)变为signed char
(8960
)。当你的价值8960
被包裹起来......
0
变为8961
,1
变为8959
,-1
变为0
, ...存储在signed char
时变为8960
(256
是8960 % 256 == 0
,NO
的倍数),因此它是{{1} }。这同样适用于256
,512
,... 256
的倍数。
我强烈建议您使用YES
,将NO
与BOOL
一起使用,而不要依赖int
之类的花哨C功能作为if
中的条件,等等。 Swift具有Bool
,true
和false
的原因,并且您无法在期望Int
的条件中使用Bool
值。只是为了避免这种混乱 ......
答案 1 :(得分:37)
对于32位BOOL是signed char
,而在64位下它是bool
。
来自objc.h
的BOOL的定义:
/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif