为什么在Objective-C中将nil预处理为((void *)0)?

时间:2017-09-27 20:31:52

标签: objective-c xcode pointers clang c-preprocessor

使用Xcode 8.3.2,如果我在Objective-C文件中使用tasks: - name: EC2 Instance ec2: aws_access_key: <hidden> aws_secret_key: <hidden> instance_type: c4.4xlarge image: ami-221ea342 monitoring: yes region: us-west-2 wait: yes volumes: - device_name: /dev/xvda volume_type: gp2 volume_size: 80 - device_name: /dev/xvdf volume_type: gp2 volume_size: 500 exact_count: 2 count_tag: Component: "MyEC2" Environment: Production <snip> instance_tags: Component: "MyEC2" Environment: Production <snip> 并选择Product&gt;执行操作&gt;预处理“MySourceFile.m”,nil变为nil。我有几个问题:

  1. 如果((void *)0)是语言的一部分,为什么预处理器会对它做任何事情?为什么编译步骤不直接接受nil
  2. nil的整个点是空对象指针时,为什么nil会变成((void *)0)?为什么不对((id)0)这样的内容进行预处理,因为像this one这样的来源定义了它?

2 个答案:

答案 0 :(得分:3)

“语言的一部分”并不一定意味着“编译器的一部分”。例如,C标准强制NULL为宏。没有Objective-C标准,因此Objective-C实现者可以做他们想要的事情。重要的是,当您使用整个编程环境时,您可以访问表示没有对象的nil标记。

nil并不总是与NULL相同:它used to be defined as just 0,然后在2007年左右它是changed to __DARWIN_NULL,在最近的版本中它将是nullptr在Objective-C ++模式下,__DARWIN_NULL。 (__DARWIN_NULL来自<sys/_types.h>。)

Xcode对于找到“伪关键字”的定义有点讨厌。我发现对于Xcode视为关键字的宏(如nilNULL),找到它们定义位置的最佳方法是重新定义它们并查看错误消息。

#define nil 0
        ^
foo/main.m:29:9: warning: 'nil' macro redefined [-Wmacro-redefined]

In module 'Foundation' imported from foo/main.m:9:
In module 'CoreFoundation' imported from /.../Frameworks/Foundation.framework/Headers/Foundation.h:6:
In module 'Dispatch' imported from /.../Frameworks/CoreFoundation.framework/Headers/CFStream.h:15:
In module 'os_object' imported from /.../include/dispatch/dispatch.h:66:
In module 'ObjectiveC' imported from /.../include/os/object.h:99:
/.../include/objc/objc.h:108:12: note: previous definition is here
#   define nil __DARWIN_NULL
           ^

答案 1 :(得分:2)

  1. nilNULL都不是(Objective-)C语言本身的一部分,也就是说它们不是关键字而是库/框架中预定义的常量/宏。

  2. 这来自C标准:

  3.   

    值为0的整型常量表达式或类型为void *的表达式称为空指针常量。如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与不等于指向任何对象或函数的指针进行比较。

    并且通常包括强制转换以使其清楚,结果是空指针常量。对于C指针类型使用NULL和对Objective-C对象引用类型使用nil也是惯例,它们都扩展为空指针常量。