【问题标题】:Are variable-length arrays really not allowed in C90?C90 中真的不允许变长数组吗?
【发布时间】:2013-07-13 07:57:05
【问题描述】:

我正在阅读 C Primer Plus 中的 VLA,这本书严格地说,将 VLA 引入 C 是从 C99 标准开始的。每当我尝试在 for 循环的标头中声明循环控制变量时,gcc 都会通知我此操作仅在 C99 模式下允许。但是,以下测试代码可以编译并运行(尽管它会打印垃圾变量,考虑到没有初始化任何数组元素,这是可以预料的)。

#include <stdio.h>

int main(){
    int x; 
    int i = 9; 
    int array[i]; 

    for(x = 0; x < i; x++)
        printf("%d\n", array[x]);

    return 0; 
}

如果我不是 C99 模式,这怎么可能是合法的?

【问题讨论】:

标签: c arrays gcc gcc-extensions


【解决方案1】:

如果我不是 C99 模式,这怎么可能是合法的?

不是。然而,GCC 允许它作为编译器扩展

您可以通过传递 -pedantic 标志来强制 GCC 对此进行严格处理:

$ gcc -std=c89 -pedantic main.c
main.c: In function ‘main’:
main.c:6: warning: ISO C90 forbids variable-size array ‘array’

【讨论】:

  • 当然这里的含义很清楚:总是使用-pedantic 编译 – 就此而言,-Wall -Wextra -Werror – 除非有令人信服的理由(遗留代码会打破)不要。
  • -pedantic 对于未使用的参数可能会很烦人。 Clang 还有一个-Weverything 标志,它很快就会变得非常痛苦。
  • 使用-pedantic-errors。并注释掉未使用的参数。或者不要使用未使用的参数......哦等等:P
  • @Carl 没有未使用的参数。
  • @KonradRudolph,这并不总是可能的。有时您必须实现现有的 API。
【解决方案2】:

这本书是正确的,从 C99 开始就支持可变长度数组,如果您使用以下选项构建:

gcc -std=c89 -pedantic

您将收到警告:

警告:ISO C90 禁止变长数组'array' [-Wvla]

如果您希望这是一个错误,您可以使用-pedantic-errorsgccc99 之前支持此作为 extension,您可以在 c99 模式下显式构建,您将不会看到任何错误:

gcc -std=c99 -pedantic

Language Standards Supported by GCC 页面详细介绍了 gcc 支持 C 的标准,并指出:

默认情况下,GCC 会为 C 语言提供一些扩展,这些扩展在极少数情况下会与 C 标准冲突

【讨论】:

    【解决方案3】:

    “如果我不是 C99 模式,这怎么可能是合法的?”

    编译器可以有除了严格遵守 C 标准之外的模式。

    实际上,C 标准只是一种规范。没有法律规定你必须遵守它,也没有法律规定编译器开发人员必须遵守它。

    因此允许编译器定义自己的语言变体,并使用自己的规范甚至第三方编写的规范进行编译。

    不仅如此,C 标准还定义了可扩展的语言。在保持符合 C 标准的同时,允许实现定义许多行为。 C 标准甚至指定符合标准的程序是符合标准的实现可接受的任何程序。这意味着使用编译器扩展的程序仍然是符合标准的 C 程序(在没有任何其他问题的情况下)。 (但是,它不是一个严格遵守的程序;那些是不使用扩展的程序。)

    【讨论】:

      猜你喜欢
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      相关资源
      最近更新 更多