“ Objective-C比C ++更严格地是C的超集”的确切含义是什么?


87

根据我在那阅读的内容:为什么Objective-C在Apple社区之外不那么受欢迎?

Objective-C是C的超集(实际上比C ++严格得多),因此不会出现向后兼容的问题。您可以用C语言做的任何事情都可以用Objective-C语言做。

成为超集是二元的,就像怀孕一样。Obj-C是C的超集,而C ++不是。

超集是什么意思?Objective-C将以哪种方式更接近//向后兼容C?与C ++相比,objective-C在哪种方面更遵循C哲学?

是否可以不经目标C编译器(100%兼容性)修改而编译任何C程序?

与其说是哪个更好,不如说是关于编程语言设计和兼容性的问题。

Answers:


134

我准备了一个简单的图表;它不是很漂亮,但希望能阐明这一点:

  • 红色:在C,C ++和Objective-C中有效的所有程序的集合(相对较小)
  • 绿色:在C和Objective-C中有效但在C ++中无效的所有程序的集合(甚至更小)
  • 灰色:所有在Objective C和C ++中有效但在C中无效的程序集(据我所知为空)
  • 蓝色:仅在目标C中有效的所有程序的集合(相对较大)
  • 黄色:仅在C ++中有效的所有程序的集合(最大)

有效的C程序集(红色和绿色)是有效的Objective C程序集(蓝色)的严格子集

在此处输入图片说明


14
那么目标C ++呢?
user1115057 2013年


19
您认为黄色比蓝色“大”多少?直觉告诉我,这两个集合将无穷无尽。
2013年

4
@wim:两者都表示为R ^ 2的不可数子集;)这是相同的技巧,您将在Q内看到N,尽管它们的大小相同(并且N是Q的严格子集)。
Maciej Piechotka

3
我在考虑了一下,并意识到ObjC ++集合实际上并不能解决所有这些问题。它是C ++的超集,但不是ObjC的严格超集。合法的C是相同的程序,但非法的C ++(绿色区域)是非法的ObjC ++。
罗布·纳皮尔

62
  1. 超集是什么意思?

    它们表示严格的超集。任何有效的C程序都可以使用Objective-C编译器进行编译。某些有效的C程序将无法使用C ++编译器进行编译。

  2. Objective-C将以哪种方式更接近//向后兼容C?

    这是一个简单的例子:

    int *foo = malloc(12);

    使用C和Objective-C进行编译,但不能使用C ++进行编译。当然,还有其他示例。

  3. 与C ++相比,objective-C在哪种方面更遵循C哲学?

    全部-Objective-C是C的严格超集。

  4. 是否可以不经目标C编译器(100%兼容性)修改而编译任何C程序?

    是。


2
是的,那很好。如果您愿意找出要使用的低级运行时函数,那么可以说,GUI也不需要Objective-C。
卡尔·诺鲁姆

3
主要是哲学上的。
卡尔·诺鲁姆

2
+1很棒的解释。我建议“ C哲学”的问题有点含糊,但是大多数观察者可能会同意C的“目标”和ObjC的“目标”确实有所不同。C的意图是与硬件非常接近,同时提供一些有用的可移植性抽象,而ObjC的目标是将SmallTalk方法引入C。由于可可粉近年来已成为ObjC不可或缺的一部分,因此这种差异更加明显。C阵列和NSArray的“原理”(设计方法)当然是非常不同的。
Rob Napier 2013年

2
那完全取决于程序。在Objective-C程序中,您可能不会做太多的C风格的事情。那为什么要使用Objective-C?
卡尔·诺鲁姆

1
@ user1115057:您不必太担心如何考虑事物。编写可编译为C(或至少看起来像C)的C ++代码有两个问题。一个是您没有获得C ++的任何好处,但这就是您的要求。重要的一点是,您使用的不是C的C语言却是残破的方言。您应该使用C编译器编译C代码,并将其链接到C ++代码。这后一种关注不使用Objective-C的应用,因为Objective-C的子集,编译为C, C.
史蒂夫·杰索普

31

从头开始,C ++被设计为“更好的C”,解决了C ++作者通过该语言进行的实际和可感知的设计遗漏。这个设计决定的结果是,X当一个有效的C程序不能保证X在由C ++编译器处理时可以编译,更不用说运行。这些更改涉及诸如字符串文字(它们变为const char*),void指针的分配,enums与整数类型之间的转换,复合赋值运算符的语义等基本构造。

而且,一旦C99出现,就将其纳入更新的C标准的功能从更新的C ++标准中删除了。再次,忽略了非常重要的语言功能-最值得注意的是指定的初始化程序和可变大小的数组。

相反,Objective C被定位为C的超集,要求所有有效的C程序都可以使用Objective C编译器进行编译。


4
我已经回答了这个问题,因为我知道什么是“超集”,但是我对Objective-C一无所知。我在另一个SO问题中看到一个说法,即有效的C代码片段int nil = 0; nil++;未编译为Objective-C。问题出在哪里,Objective-C提供的标头很明显吗?一旦包含标头,它们就可以像C标头一样完全破坏代码了?因此,该摘要的作者不应将其包括在内。
Steve Jessop

2
“ nil”实际上是#define而不是关键字。您会看到问题,因为其中包含objc / objc.h。这类似于您尝试创建名为YES的变量时将看到的问题。(Xcode突出显示它们好像是真正的关键字,因为这样思考起来要容易得多;但是它们被实现为简单的C代码。)
Rob Napier

4
顺便说一句,如果您对ObjC如何生活在C之上感兴趣,那么值得在objc.ha周围摸索一下。您会认为关键字(id,BOOL,Class,nil等)只是简单的类型,结构,并进行定义。您甚至可以在纯C中手动实现消息传递。永远不要那样做。:D但是可以。github.com/iosptl/ios6ptl/blob/master/ch28/Runtime/MyMsgSend.c
Rob Napier

2
@DanNeely:罗布·纳皮尔(Rob Napier)说“永远不要那样”,作为对链接文件的评论。链接的文件不是 Objective-C运行时,它只是一个快速的技巧,它显示了消息传递的真正工作方式。
Dietrich Epp 2013年

1
链接的文件并没有说明ObjC消息传递的复杂程度。它证明了可以从C中获得运行时,并且原则上您可以将ObjC代码转换为纯C。但是…这与构建它的速度差不多。它依赖于我知道方法的返回类型(对于某些返回类型,我可能需要了解处理器类型),并且我精心选择了不带参数的方法。完整的解决方案有许多巧妙的技巧(零件必须放在汇编器中,因为它们会欺骗堆栈框架)。您永远不要尝试重建它。
罗布·纳皮尔

12

“ Objective-C是C的超集”意味着每个有效的C程序都是有效的Objective-C程序(含义相同)。

有时表示,虽然不是由C ++专家认为C ++是C.这的一个超集是不准确的,这就是为什么你报的是使两相比较的一个大问题。


9

目标C是对C的一组向后兼容扩展。之所以可行,是因为目标C的功能以两种非常简单的方式来界定:

  • 角色的使用@。该字符当前不在C语言中使用。
  • 调用方法的简单语法扩展[obj method:argument]。在C语言中,方括号用于数组下标的方式非常特殊,因此这是无效的C语法。以无效语法为基础的扩展名不会更改宿主语言中任何有效内容的含义。

很容易看出,无论多么简单,使用Objective C扩展的程序都不能成为严格符合ISO C的程序。而且,根据定义,每个ISO C程序都可以声明为有效的Objective C程序。目标C可以轻松跟踪C99和C11等开发。

另一方面,C ++不仅是对C的扩展;这是另一种语言,它改变了C的某些语法的含义。C++和C是分别维护的,因此它们的关系会随着时间而改变。例如,C获得了C ++中完全不存在的新功能,并且很可能不会融入C ++中,例如C99可变长度数组。C ++无法轻易获得新的C功能。

如果您编写一个可移植的C程序,则它应同时是一个Objective C程序。但是,还需要格外小心,以便它也是具有相同含义的C ++程序。(这种做法并非闻所未闻,它所需要的方言被非正式地称为“ Clean C”)。

在被视为C ++时会中断的C程序的一个简单示例是使用C ++关键字作为标识符的任何C程序,例如classvirtual。目标C不引入任何保留关键字。它具有由@字符引入的新关键字,例如@interface

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.