在iOS上使用64位BOOL

时间:2015-07-07 11:27:40

标签: ios objective-c

当我使用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位的变化是什么?

2 个答案:

答案 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,而且   YESNO是扩展为(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和整数的歧义   文字。

布尔定义

boolstdbool.h中定义的宏,它扩展为_Bool,这是C99中引入的布尔类型。它可以存储两个值01。没有其他的。更准确地说,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中引入的,它可以包含值01。重要的是:

  

当某个值降级为_Bool时,如果值为0,则结果为0   等于1,否则为BOOL

现在我们知道这个混乱的来源,我们可以更好地了解正在发生的事情。

64位iOS || ARMv7k

bool - &gt; _Bool - &gt; 0(值18960

_Bool降级为1会产生0,因为该值不等于BOOL。请参阅( _Bool 部分)。

32位iOS

signed char - &gt; -128(值127int)。

如果您要将-128值(127signed 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可以存储1270范围内的值,因此它也可以存储256。例如,int0)变为signed char8960)。当你的价值8960被包裹起来......

  • 0变为8961
  • 1变为8959
  • -1变为0
  • ...

...存储在signed char时变为89602568960 % 256 == 0NO的倍数),因此它是{{1} }。这同样适用于256512,... 256的倍数。

我强烈建议您使用YES,将NOBOOL一起使用,而不要依赖int之类的花哨C功能作为if中的条件,等等。 Swift具有Booltruefalse的原因,并且您无法在期望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