可以在Clang6.0的stddef.h文件中找到NULL和nullptr的声明:#undefNULL#ifdef__cplusplus#if!defined(__MINGW32__)&&!defined(_MSC_VER)#defineNULL__null#else#defineNULL0#endif#else#defineNULL((void*)0)#endif#ifdef__cplusplus#ifdefined(_MSC_EXTENSIONS)&&defined(_NATIVE_NULLPTR_SUPPORTED)namespacestd{typedefdecltype(nullptr)nullptr_t;}using::std::nullptr_t;#endif#end早在1972年,在C语言诞生初期,常量0就具有常量和空指针的双重身份。C使用预处理宏NULL来表示一个空指针,让NULL和0分别表示一个空指针和常量0。NULL可以定义为((void*)0)或0。C++不遵循C的规则,不允许将void*隐式转换为其他类型的指针。为了使代码char*c=NULL;可以编译,NULL只能定义为0。这样的决定使得函数重载无法区分代码的语义:voidfoo(char*);voidfoo(int);C++建议将NULL定义为0,所以foo(NULL);会调用foo(int),这不是程序,它违反了代码的直观性。0的歧义在这里引起了混淆。C++11引入了一个新的关键字来表示空指针常量:nullptr,将空指针和整数0的概念分开。nullptr的类型为nullptr_t,可以隐式转换为任何指针或成员指针类型,并且可以也可以与他们比较平等或不平等。而且nullptr不能隐式转换为整数,也不能与整数进行比较。为了向后兼容,0仍然可以表示空指针常量。char*pc=nullptr;//OKint*pi=nullptr;//OKinti=nullptr;//errorfoo(pc);//callfoo(char*)PS:__MINGW32__是MinGW编译器的预定义宏。_MSC_VER是MicrosoftC/C++编译器-cl.exe在编译代码时预定义的宏。_MSC_VER的值表示cl的版本。当您需要为特定版本的cl编写代码时,您也可以使用此宏进行条件编译。nil和NilObjective-Cnil被定义为实例对象的空值(一个空实例)Nil被定义为类对象的空值(一个空类)nil和Nil在objc.h和MacTypes.h中有等效的声明文件:#ifndefNil#if__has_feature(cxx_nullptr)#defineNilnullptr#else#defineNil__DARWIN_NULL#endif#endif#ifndefnil#if__has_feature(cxx_nullptr)#definenilnullptr#else#definenil__DARWIN_NULL#endif#endif根据Clang3.7文档支持的功能是has_hasClangandstandardizedinthecurrentlanguagestandardor0ifnot”,__has_feature(cxx_nullptr)用于确定是否支持C++11中的nullptr特性。nil和Nil都是Objective-C中的__DARWIN_NULL宏定义。按住CMD鼠标点击进入_types.h:#ifdef__cplusplus#ifdef__GNUG__#define__DARWIN_NULL__null#else/*!__GNUG__*/#ifdef__LP64__#define__DARWIN_NULL(0L)#else/*!__LP64__*/#define__DARWIN_NULL0#endif/*__#64__*endif/*__GNUG__*/#else/*!__cplusplus*/#define__DARWIN_NULL((void*)0)#endif/*__cplusplus*/因为Objective-C不是C++代码,所以倒数第二行#define__DARWIN_NULL((void*)0)此时是高亮的,也就是说nil和Nil的最终本质是((void*)0)PS:其实如果只看Objective-C中nil和Nil的定义,你不用这么麻烦,只需要看看RuntimeReference中的Objective-C“Constants->NullValues”就够了。SwiftSwift1.2目前只有nil而不是Nil。为了安全起见,Swift添加了Optional类型作为容器。例如,一个盒子可能包含某种类型的对象,也可能是空的(nil)。盒子也可以嵌套和移除,但这都是基于安全解析、绑定等。Swift中的nil与Objective-C中的nil不一样。在Objective-C中,nil是指向不存在的对象的指针。在Swift中,nil不是指针——它是一个确定的值,用于指示值不存在。任何类型的可选值都可以设置为nil,不仅仅是对象。PS:关于Swift中Optional类型的更多信息,可以参考我的另一篇博文:OptionalsandOptionalChaininginSwiftPS:曾几何时,Swift的nil并不是一个字面值,而是NilType类型的唯一实例。但这一切都已成为历史。NSNull.h中NSNullNSNull的定义:@interfaceNSNull:NSObject
