1.发现问题
学习OC时,OC基础教程一书中对BOOL的介绍是,其本质是一个unsigned char类型,所以当你赋值一个多字节数据时产生字节截断,将会有错误的结果。
#import <Foundation/Foundation.h>
int main(int argc, char * argv[]) {
@autoreleasepool {
BOOL a= 0x2300;
NSLog(@"%s %d",a?"YES":"NO",sizeof(bool));
return 0;
}
}
在MacOSx的command line tool工程中将会输出"NO 1",
而在iphone的工程中则会输出"YES 1"。
显然BOOL型变量大小确认是1字节了,那为什么一个产生了截断,一个没有呢?
2.试图解决
查看Xcode的帮助文档
Description: typedef bool 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
这里有一个宏定义区分了iphone设备和mac,使得mac上运行的发生了我们所说的字节截断导致的现象。那么bool
为什么会导致没有发生字节截断呢?
找到C的<stdbool.h>
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GCC.
*/
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus ,应用于C++里,这里不用处理它*/
/* Supporting <stdbool.h> in C++ is a GCC extension. */
#define _Bool bool
#define bool bool
#define false false
#define true true
#endif /* __cplusplus */
/* Signal that all the definitions are present. */
#define __bool_true_false_are_defined 1
#endif /* stdbool.h */
发现
#define bool _Bool
3.开始推断
C2008草案中说:
Anobject declared as type _Bool is large enough to store the values 0 and1.
也就是说,只规定了_Bool类型的大小是至少能够存放0和1这两个值。并没有规定具体的大小,这交给编译器自由发挥了。显然xcode编译器对其的处理方式是所有非0值为1,0值位0了。至于为何不在mac中支持 Bool
,出于何种考虑我还没找到。。。
浪费了较多时间查这个,还是记录一下。
对于这个小细节差异,一句话便是,这一切都是命运石之门的抉择了。。。
网友评论