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:
以前,
BOOLtypes仅仅是signed char的typedef,YES和NO是分别扩展到(BOOL)1和(BOOL)0macros。 为了支持@YES和@NOexpression式,现在使用<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