【问题标题】:Is objective C 2.0 a proper superset of C?Objective C 2.0 是 C 的适当超集吗?
【发布时间】:2010-06-03 06:51:46
【问题描述】:

我听说objective-C 是C 的适当超集,但objective-C 是2.0 吗?

我问的原因是不是,或者我误解了“正确的超集”这个短语,因为这段代码是有效的 C 语法:

#import <stdio.h>

int main () {
    char *nil = "hello";
    printf("%s\n",nil);
}

但不能在 Objective-C 2.0 中编译。显然,这是一个很容易解决的问题,但是我正在写一篇论文,感觉这是应该指出的。

【问题讨论】:

  • 即使您没有包含任何 Objective-C 框架或运行时标头,它也无法编译的原因是因为您的项目可能有一个预编译的标头 可以 包括 Foundation 框架头文件(以及定义 nil 的头文件)。
  • 它确实为我编译,使用 gcc 4.4 和命令行 gcc some_file.m -o some_file。因此,虽然可能有有效的 C 程序不是有效的 Objective-C,但这不是一个。
  • This question 为“严格的超集”神话指出了一个更尖锐的反例:任何使用id 作为标识符的 C 程序都将无法编译为 Obj-C。

标签: c objective-c compatibility superset


【解决方案1】:

nil 不是关键字。 nilobjc.h [在 Mac OS X 上] 中定义(__DARWIN_NULL 实际上只是 NULL):

#ifndef nil
#define nil __DARWIN_NULL   /* id of Nil instance */
#endif

也就是说,nil 并不是编译语言的真正组成部分,而是系统库在编译期间使用的约定。

分叉,很明显。不过,您真的可以在没有nil 的情况下编译Objective-C 源代码。

这类似于问“我可以编写一个具有名为deflate 的变量的工具,同时仍使用zlib.h 接口吗?”。当然。但是会很丑。

事实上,编译器不会自动包含 objc.h。这个:

#include <stdio.h>

int main() {
    int nil = 5;
    fprintf(stdout, "Hello %d\n", nil);
    return 0;
}

一旦您删除了导入 Foundation 的预编译/前缀头文件,因此可以在标准 Foundation 工具项目(在 main.m 中)中正常编译和运行,从而导入 objc.h。 (所以,是的,开箱即用,Xcode 模板 do 会通过导入 Cocoa/Cocoa.hFoundation/Foundation.h 来导入 objc.h。)

【讨论】:

  • 所以您是说 XCode 在编译我的代码时,会为编译器提供一些导致 nil 被定义的选项?因为我确实注意到它是在哪里定义的,但我只是假设它是 Apple 对 GNU C 编译器所做修改的一部分......
  • 问题不在于您是否“可以在没有 nil 的情况下编译 Objective-C 源代码”。关键在于你是否可以编译使用 nil 作为 Objective-C 的有效 C。
  • 关注包括...某处#included &lt;objc/objc.h&gt;; Foundation、AppKit、Cocoa 等等。 IIRC,编译器不会自动包含它(我可能错了——没有objc.h的Objective-C我没有考虑太多)。
  • @Matthew 你可以。但这将是一个彻头彻尾的痛苦,因为您将无法遵循 Objective-C 的标准模式和标准运行时或系统库。但是,同样,这不是语言问题……这是图书馆问题。
  • 编译器不会自动包含它。
【解决方案2】:

Objective-C 是 C 的适当超集,因为在 C 中工作的所有内容都适用于 Objective-C。

但是,

因为它是一个超集,所以它添加了一些new types, definitions and directives

这意味着如果你使用像nil 这样的保留定义,你就会遇到严重的麻烦。

这就是上面的程序无法编译的原因。

【讨论】:

  • +1 - 我知道这条评论已经晚了(这是一篇旧帖子),但你的回答正是我的想法。如果它是一个正确的超集,它会添加子集中不存在的东西。这意味着为子集语言编写的代码在超集语言中可能会有不同的解释,甚至会抛出错误,因为您使用了保留字作为变量名。
  • 添加新的类型、定义或指令,如果这样做会使任何以前有效的程序中断或改变其语义,则会使objective-c 不再成为超集。当然,除非你必须在有效的 C 中做一些不可能的事情才能启用它们。
猜你喜欢
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多