c - C99 之前的 C 在 for 循环中没有初始声明的原因是什么?

标签 c c89 ansi-c

为什么原来的C语言不支持for循环初始化中的初始声明?

显然,最初的创作者,然后是 C99 之前的标准化,并没有那样指定。但我似乎找不到任何理由来解释为什么做出了这样的设计选择。

我似乎找到的最接近答案的是 this answer解释如何禁止混合声明和代码以允许编译器在重要时单回传。乍一看,for 循环语句中的声明与混合代码的声明存在相同/相似的问题是有道理的。

但是,C99 之前的 C 确实支持 block 开头的声明:

{
    unsigned int i;
    for(i = 0; i < WHATEVER; i += 1)
    {
        /* ... */
    }
}

我个人看不出它的编译器逻辑与这个有什么本质上的不同:

for(unsigned int i = 0; i < WHATEVER; i += 1)
{
    /* ... */
}

在我看来,如果编译器可以执行前者的单次传递,那么它也可以执行后者。它可能需要 for 语句总是创建一个范围 block (即使后面只有一个语句而不是 { ... } block 的语句),但我想不出这种语义的方法来破坏任何其他 C99 之前的 C 代码(for 语句后跟一个 block ,在这种情况下它已经是“作用域”,或者它后跟一个语句,在这种情况下,无论如何都不允许在该单个语句中进行新的声明)。

那么,为什么最初省略了这个语法“功能”?我是否认为在不违反当时的绩效目标的情况下提供支持是微不足道的?当时已知的语言解析器/编译器技术是否让它看起来更难?它是否只是因为极简主义设计/心态而被省略,因为在功能上可以做同样的事情(block around for loop)?或者是否有明确的语言设计原因反对它(例如,Go 最初是如何排除异常的,因为设计者认为这有助于更好的语言)?

我看过的地方

  • 我已经尝试在这里和通过一般的网络搜索找到这个问题的答案,但没有成功:我想到的所有搜索词似乎都充满了关于 C for 循环初始声明的混淆问题,“在外部使用C99 模式”错误消息等(除了搜索词“基本原理”,它引导我找到有用的信息,但没有具体回答这个问题)。
  • 我搜索了 this article由丹尼斯·里奇 (Dennis Ritchie) 亲自开发该语言,但没有发现任何东西。
  • 我搜索了我的 C 编程语言(第 2 版)副本,首先阅读了实际的 for 循环解释部分,然后检查了索引以查找其他提及“for”/“for 循环”的内容。我已经阅读了其他几个我认为可能会提到它的地方,但一无所获。

最佳答案

我认为没有任何具体决定排除此类功能,也没有理由这样做。

虽然看起来设计师(Kernighan、Ritchie 等)考虑了所有的可能性,并且只有在深入而有意义的考虑之后才排除功能,但现实是设计 C 的早期(就像一个相当少数其他编程语言)遵循一种更为谦逊的哲学,例如“从小处着手,除非程序员被阻止做某事,否则不要为添加功能而烦恼”。

for 循环中的变量初始化等功能为程序员提供了方便 - 它们的缺席并没有阻止事情的完成。因此,即使有人乞求或宣传这样的功能(可能没有),它的优先级顺序也可能下降。

至于事情是如何演变的......

在 1999 年之前,变量声明位于 C 语言 block 的开头(代码以 { 开始并以结尾的 } 结束),而不是在其他语句中。这是事情最初在准标准 (K&R) C 和之前的语言如 B(实际上是之前语言的缩减派生)中的工作方式。

for 循环中的变量声明/初始化首先被引入到 C++ 中。它很早就出现了(例如 ARM 中的第 19 节),并最终在 1998 年底批准的第一个 C++ 标准中引入。

C 标准委员会在起草 C++ 标准的过程中(用了十年时间)讨论了将 C++ 的某些特性引入 C 的过程。该讨论通常主要围绕“在C break 如果我们添加这个?”。许多编译器供应商已经在他们的 C 编译器中实现了几个这样的功能作为可选扩展(或者他们的 C 编译器实际上是 C++ 编译器,具有禁用与 C 不兼容的 C++ 功能的设置),因此关于添加这些功能的讨论非常简短。因此,那些很容易从 C++ 添加到 C 的特性出现在 1999 年的 C 标准中。 for 循环中的变量声明/初始化是这些功能之一。

从那段历史来看,没有证据表明有任何特定的决定或理由将这些功能从早期 C 中排除 - 简而言之,可能只是没有想到。

关于c - C99 之前的 C 在 for 循环中没有初始声明的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35110985/

相关文章:

c - 读取结构中的数组会导致段错误

c - 使用文件在 C 中保存结构

c - 如何将C中的字符转换为字符数组?

c - 所有结构标识符都自动向前声明

c# - 使用 C# 进行 Ansi C 编程还是以 C# 方式编程?

c - 当文件描述符关闭时,有什么方法可以执行回调(在 Linux 上)

c - 输入 : a2b3c4 and Output: aabbbcccc

c - 使用动态分配的内存初始化结构

c - 在 C89 中,我似乎无法从现有的字符数组中创建字符数组

c - IOCCC 1988/isaak.c - 为什么即使在 ANSI 化之后也没有输出?