在可可头?在昨天的会议上,佩洛做了一个很好的OBJC测试。当最后一个问题要被评估时,竞争激烈,剩下三个人的得分相同:Objective-C在C中添加了多少保留关键字?
随后进行了激烈的辩论。所有人都同意@interface和@implementation等都是预处理器指令,而不是关键字,但是像in这样的指令怎么样?它可能是关键字,但不是保留关键字。例如,以下代码编译时不会出现错误或警告:
1 2 3
| NSArray* in;
for (in in in)
NSLog(@"bwahahaa"); |
我们得出的结论是,objc没有在c中添加保留的关键字,并且有人赢得了一本似乎收入颇丰的书。
但是今天我尝试了一些更系统的对编译器的滥用,比如:
1 2 3
| int self = 45;
self++;
int y = self; |
这编译得很好,同样的代码可以代替self替换BOOL, bycopy, inout, oneway, byref, SEL,和IMP。
使用id作为变量名,编译第一行和最后一行,但不编译第二行。同样适用于Protocol和Class。
使用super编译第一行,但不编译第二行和第三行。
对于YES、NO和NULL,这三行都无法编译,可能是因为它们只是定义为true、false和nil。
在我看来,很多这是GCC变得困惑,我不太确定它反映了什么是和不是Objective-C中的保留关键字。例如,为什么可以使用self作为in t的名称,而不是super?
第一个任务总是有效的(除了有"是"、"否"和"空")这一事实似乎支持这样一种观点:没有一个候选人在技术上是保留的关键字,在C中找不到。还是?
有人能对这个棘手的问题给我们一个权威的解释吗?
几个人的荣誉危在旦夕。
编辑:正如Nikolai Ruhe指出的,我们需要一个"关键字"的清晰定义来继续。尼科引用维基百科的一篇文章说,关键字是"一个有特殊含义的词或标识符"。
我认为从同一篇文章中使用这个定义是合理的:
In many languages, such as C and
similar environments like C++, a
keyword is a reserved word which
identifies a syntactic form. Words
used in control flow constructs, such
as if, then, and else are keywords. In
these languages, keywords cannot also
be used as the names of variables or
functions.
此外,正如本文所述:
Typically, when a programmer attempts
to use a keyword for a variable or
function name, a compilation error
will be triggered.
那么,从这个意义上讲,是否有任何在语言的正式规范中预先定义的、不能用作用户定义名称的保留关键字?
- 这里有一些相关资料:stackoverflow.com/questions/25749/…
所有人都同意@interface、@implementation等都是预处理器指令,而不是关键字。
然后一切都错了。#import和#pragma是预处理器指令。@interface, @implementation, @protocol等是objective-c的关键字,是编译指令。自从下一次扩展GCC来编译Objective-C,而没有Stepstone最初的Objective-C预处理器实现之后,它们就不再是预处理器指令了。
- 那么这就意味着@interface是一个关键字(从上面的编辑所述的意义上讲),但id不是,因为编译器拒绝编译,例如"in t@interface=1";但很高兴地使用id作为int的名称。但是,编译器也不允许"int@icecream=1;"。那我们该怎么办?#import--预处理器指令@interface--编译器指令@--保留字符id/self/in--在某些上下文中是特殊含义,但不保留
- ID是typedef。你可以在objc.h中找到它
回复:Nikolai Ruhe认为自我是一个关键词
self是id型(类似于_cmd也是参数,SEL型)而不是关键字的客观c方法的参数。nil是一个扩大到NULL的宏。我有点失望,因为super没有扩展到宏,也不是一个参数。
从维基百科条目:
Objective-C is a thin layer on top of C, and moreover is a strict superset of C. It is possible to compile any C program with an Objective-C compiler, and to freely include C code within an Objective-C class.
这将阻止Objective-C在语言中添加任何受限制的关键字。
- 这是一个非常好的观点,尽管GCC显然没有完全遵守这一限制。
- 结论是不正确的。语言的超集可以使用原始语言中非法的术语添加关键字。这正是Objective-C所做的。
- 关于super不是宏:编译器必须能够识别super,因为它必须使用正确的消息类型(调用objc_msgSendSuper而不是objc_msgSend)。super指向与self相同的对象,因此也没有多大的意义来提出另一个论点。
- Objective-C是一个超集,它并不排除添加额外的受限关键字,而是允许所有C程序用Objective-C编译器编译。
- 乔恩:为什么?正如NSResponder指出的,Objective-C确实添加了关键字。但是编译器也编译所有C程序。
- @jon:b.t.w:实例方法的隐式self参数不是id类型,而是静态类型化的。
- @尼古拉:我认为乔恩的意思是,一个带有变量super的C程序,它将在C下编译,不会被Objective-C编译器接受(至少不是gcc),在这方面,它似乎打破了严格的超集要求。
- @felixyz:在gcc4.0、gcc4.2和clang中,使用super作为C函数中变量的名称编译很好。在方法中使用它当然是一个错误。没有违反要求。我的意思是乔恩的推理是错误的:严格的超集可以在不破坏任何东西的情况下向语言添加关键字。
- @Nikolai Ruhe:我承认你的观点:super是否可以在一个方法中用作变量名并不重要,只要它是在一个C函数中编译的。而@在C标识符中不是有效字符,因此不允许@interface等作为变量名也不会打破严格的超集要求。
- @费利西兹:谢谢你让我说得更清楚。
1995年原著附录B中的语法将super定义为"文字符号"终端,这是消息接收者语法中的一个特例。
in文字符号是objc 1.0中协议限定符的一部分,并在objc 2.0中的快速枚举语法中重用(objc 2.0没有正式的语法定义afaik)。
id被定义为类型说明符的一部分,与void、char、unsigned和typefed类型等一起。如果您调用void作为关键字,那么id也是。
您可以查看Objective-C编程语言。
据我所知,该文档没有将任何内容归类为"保留字"。@implementation和@interface等称为"编译器指令"。
维基百科将关键字定义为:
In computer programming, a keyword is a word or identifier that has a particular meaning to the programming language.
我会把它翻译成:语言中的关键字在语法上是非终结词。(顺便说一句,语法本身不包含"关键字"这个词,所以没有混淆)。
语法中的终端是:
- 无效
- 烧焦
- 短的
- int
- 长的
- 浮动
- 双重的
- 签署
- 无符号
- 身份证件
- 康斯特
- 不稳定的
- 在里面
- 外面的
- 输入输出
- 副复制品
- 拜雷夫
- 单向
- 自己
- 超级的
- @接口
- @结束
- @实现
- @结束
- @接口
- @结束
- @实现
- @结束
- @协议
- @结束
- @班
- 问题是objc可以将哪些保留关键字添加到c中。正如您在示例中看到的,您可以自由地使用"in"作为变量名,因此它显然不算作保留关键字。
- 我的意思是,"int float=45";"int id=45"编译失败;"compiles fine"告诉我们一些事情。
- 它们不是"例子"。据我所知,这是完整的清单。好吧,这取决于你想叫什么关键字。我给了你我对那个问题的答案。
- 我指的是问题中的示例代码。"语言中的关键字是非终结词"。你是说"终端机"吗?我不认为有人会调用定义关键字,那么我们为什么要@interface?谢谢你的提议,但我不相信。对我来说,任何可以用作变量名的东西都不能是(保留的)关键字。
- @Felixyz:作为回答问题的先决条件,定义关键词(通常)很重要。只有这样才能回答什么是宾语C的关键词。显然,在这方面有不同的意见。
看一下Objective-C编程语言,你会发现什么是可能的,什么是不可能的。由于在头文件中定义了一些"关键字",它们的替换可能导致观察到(和意外)的行为。
- 正确的。所以问题是:在objective-c中有没有真正的保留关键字(除了那些已经在c中保留的关键字)。
- 在其他语言意义上,没有保留的关键字。这更像是定义,它会与代码发生不良的交互。这完全取决于预处理器的工作。