BOOL与iOS上的64位
当我使用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位有什么变化?
@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(watch),它定义为bool
,其余为signed char
。
ObjC BOOL YES和NO
阅读Objective-C文字 ,你可以find:
以前,
BOOL
types仅仅是signed char
的typedef,YES
和NO
是分别扩展到(BOOL)1
和(BOOL)0
macros。 为了支持@YES
和@NO
expression式,现在使用<objc/objc.h>
新语言关键字来定义这些macros:
#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
定义的macros,它扩展为_Bool
,这是一个在C99中引入的布尔types。 它可以存储两个值, 0
或1
。 没有其他的。 更确切地说, stdbool.h
定义了四个macros来使用:
/* 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
。
现在我们知道这个烂摊子来自哪里,我们可以更好地理解发生了什么事情。
64位iOS || ARMv7k
BOOL
– > bool
– > _Bool
(值0
或1
)
将8960
降至_Bool
给出1
,因为该值不等于0
。 请参阅( _Bool部分)。
32位iOS
BOOL
– > signed char
(值-128
到127
)。
如果要将int
值( -128
至127
)存储为带signed char
,则每个C99 6.3.1.3的值不变。 否则它是实现定义的 (C99引用):
否则,新的types被签名并且值不能被表示; 结果是实现定义的或实现定义的信号被引发。
这意味着铛可以决定。 为了简化,使用默认设置,clang将其包装( int
– > signed char
):
-
-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
, - …
…当存储在有signed char
( 8960
是256
的倍数8960 % 256 == 0
)时它变为0
,因此它是NO
。 这同样适用于512
,… 256
倍数。
我强烈build议在BOOL
使用YES
, NO
,而不要依赖像int
这样的奇特C特性作为if
的条件。这就是Swift具有Bool
, true
和false
的原因,而且在Bool
预期。 只是为了避免这个混乱 …
对于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