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, YESNO是分别扩展到(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。 它可以存储两个值, 01 。 没有其他的。 更确切地说, 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中引入的,它可以保存值01 。 重要的是:

当一个值降级到_Bool ,如果值等于0 ,则结果为0 ,否则为1

现在我们知道这个烂摊子来自哪里,我们可以更好地理解发生了什么事情。

64位iOS || ARMv7k

BOOL – > bool – > _Bool (值01

8960降至_Bool给出1 ,因为该值不等于0 。 请参阅( _Bool部分)。

32位iOS

BOOL – > signed char (值-128127 )。

如果要将int值( -128127 )存储为带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可以存储-128127 ,所以它也可以存储0 。 例如256int )变成0signed char )。 而当你的价值8960缠绕…

  • 8960变成0
  • 8961变成1
  • 8959变成-1

…当存储在有signed char8960256的倍数8960 % 256 == 0 )时它变为0 ,因此它是NO 。 这同样适用于512 ,… 256倍数。

我强烈build议在BOOL使用YESNO ,而不要依赖像int这样的奇特C特性作为if的条件。这就是Swift具有Booltruefalse的原因,而且在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