BOOL with 64-bit iOS

When I use BOOL for 32-bit, I get:

 BOOL b1=8960; //b1 == NO bool b2=8960; //b2 == true 

But for 64bit, I get:

 BOOL b1=8960; //b1 == YES bool b2=8960; //b2 == true 

What has changed in BOOL from 32-bit to 64-bit?

+47
ios objective-c
Jul 07 '15 at 11:27
source share
2 answers

@TimBodeit is right, but that doesnโ€™t explain why ...

 BOOL b1=8960; //b1 == NO 

... evaluates to NO on 32-bit iOS and why it evaluates YES on 64-bit iOS. Let it start from the same beginning.

OBJC BOOL Definition

 #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 

For 64-bit iOS or ARMv7k (hours), it is defined as bool , and the rest as signed char .

ObjC BOOL YES and NO

Read Objective-C Literals , where you can find:

Previously, the bool type was just a typedef for a signed char , and YES and NO were macros that expand to (BOOL)1 and (BOOL)0 respectively. To support @YES and @NO these macros are now defined using the new language keywords in <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 

The compiler implicitly converts __objc_yes and __objc_no to (BOOL)1 and (BOOL)0 . Keywords are used to disambiguate BOOL and integer literals.

bool definition

bool is a macro defined in stdbool.h , and it expands to _Bool , which is the boolean type introduced in C99. It can store two values, 0 or 1 . Nothing more. More precisely, stdbool.h defines four macros to use:

 /* 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 was introduced in C99 and it can contain values 0 or 1 . What is important:

When the value drops to the _Bool level, the result is 0 if the value is 0 and 1 otherwise.

Now we know where this mess comes from, and we can better understand what is happening.

64-bit iOS || ARMv7k

bool bool _Bool (values 0 or 1 )

Demoting 8960 to _Bool gives 1 because the value is not 0 . See Section ( _Bool ).

32-bit iOS

bool signed char (values -128 to 127 ).

If you intend to store int values โ€‹โ€‹( -128 to 127 ) as a signed char , the value does not change to C99 6.3.1.3 . Otherwise, this implementation is defined (C99 quote):

Otherwise, the new type is signed and the value cannot be represented in it; either the result is determined by the implementation or the signal determined by the implementation.

That means clang can solve it. To make it short, with default settings, clang wraps it around ( int โ†’ signed char ):

  • -129 becomes 127 ,
  • -130 becomes 126 ,
  • -131 becomes 125 ,
  • ...

And in the opposite direction:

  • 128 becomes -128 ,
  • 129 becomes -127 ,
  • 130 becomes -126 ,
  • ...

But since signed char can store values โ€‹โ€‹in the range of -128 to 127 , it can also store 0 . For example, 256 ( int ) becomes 0 ( signed char ). And when your value 8960 wrapped around ...

  • 8960 becomes 0 ,
  • 8961 becomes 1 ,
  • 8959 becomes -1 ,
  • ...

... it becomes 0 when stored in a signed char ( 8960 is a multiple of 256 , 8960 % 256 == 0 ), so it is NO . The same applies to 256 , 512 , ... multiples of 256 .

I highly recommend using YES , NO with bool and not rely on fancy C functions like int as a condition in if , etc. For this reason, Swift has bool , true and false , and you cannot use int values โ€‹โ€‹in conditions where bool is expected. Just to avoid this mess ...

+86
Jul 07 '15 at 13:41
source share

There is a signed char for a 32-bit BOOL, while under 64-bit it is a bool .




Definition of BOOL from objc.h :

 /// 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 
+37
Jul 07 '15 at 11:36
source share



All Articles