【发布时间】:2016-05-08 18:00:31
【问题描述】:
为什么原来的 C 语言不支持 for 循环初始化中的初始声明?
显然,最初的创建者,以及 C99 之前的标准化,并没有这样指定。但我似乎找不到任何理由说明为什么做出了这种设计选择。
我似乎找到的最接近答案的是this answer,它解释了如何禁止混合声明和代码,以便在重要时允许编译器单次返回。乍一看,for 循环语句中的声明与混合代码的声明存在相同/相似的问题是有道理的。
但是,C99 之前的 C 确实支持在块开始处声明:
{
unsigned int i;
for(i = 0; i < WHATEVER; i += 1)
{
/* ... */
}
}
我个人并不认为它的编译器逻辑与这个有什么本质不同:
for(unsigned int i = 0; i < WHATEVER; i += 1)
{
/* ... */
}
在我看来,如果编译器可以执行前者的单遍,它也可以执行后者。它可能需要 for 语句 always 创建一个范围块(即使后面只有一个语句而不是 { ... } 语句块),但我想不出一种方法这种语义会破坏任何其他 C99 之前的 C 代码(for 语句后跟一个块,在这种情况下它已经“作用域”),或者它后跟一个语句,在这种情况下不允许新的声明无论如何,在那个单一的声明中)。
那么,为什么最初省略了这个语法“功能”?我认为在不违反当时的性能目标的情况下支持是微不足道的,我错了吗?当时已知的语言解析器/编译器技术是否使它看起来更难?它只是因为极简设计/心态而被省略了吗,因为在功能上可以做同样的事情(阻塞 for 循环)?或者是否有明确的语言设计理由反对它(例如,Go 最初是如何排除异常的,因为设计者认为这会产生更好的语言)?
我看过的地方
- 我已经尝试在这里和通过一般的 web-search-fu 找到答案,但没有运气:我想到的所有搜索词似乎都充满了关于 C for 循环初始声明的困惑问题,“用于外部of C99 mode”错误消息等(除了搜索词“rationale”,它引导我找到有用的信息,但没有具体回答这个问题)。
- 我在 Dennis Ritchie 本人的 this article 上搜索了有关开发该语言的内容,但没有发现任何内容。
- 我搜索了我的 C 编程语言(第 2 版)副本,首先阅读了实际的 for 循环解释部分,然后检查索引中是否有其他提及“for”/“for 循环”的内容。我已经阅读了其他几个我认为可能会提到它的地方,但一无所获。
【问题讨论】:
-
在 C99 之前,C 不允许您在块开头定义变量。在
for循环的控制部分中定义的变量不在块的开头,因此不期望它们会被支持。 C++ 引入了这两个概念(在块中的任意位置定义变量,以及在forloo 的控制部分定义的变量)——C99 也添加了它们。 -
只有作者才能回答这个问题,其他人只是猜测。这些类型的问题被认为是题外话。
-
@JonathanLeffler 我赞成您的评论。您认为将其纳入当前给出的答案会更好吗?它类似于答案中的“除非程序员停止完成某事,否则不要添加功能”的想法,但捕捉到的看待问题的方式略有不同。
-
@cimmanon 我不这么认为(“推测”的含义与“基于现有证据的合理推理”有很大不同是有用的):流行思想的历史证据时间(当时计算机科学家的话)、技术证据表明它会如何恶化当时编译器的性能,甚至合理的逻辑推理也可以产生比推测更确定/客观的答案。
-
彼得的段落以“1999 年之前”开头,下一段用稍微不同的措辞涵盖了我的观点;我认为没有必要编辑他的答案来涵盖我的观点。