C++编译器中的可变长度数组(VLA)

Bia*_*sta 9 c++ dynamic-arrays

我们已经知道,VLA(在C99中标准化)不是C++标准的一部分.

所以下面的代码在C++中是"非法的":

void foo(int n) {
  int vla[n];
  for (int i = 0; i < n; ++i) {
    vla[i] = i;
  }
}
Run Code Online (Sandbox Code Playgroud)

尽管编译器(g ++clang ++)接受代码作为有效语法,但只有启用情况下才会生成警告 .-pedantic

ISO C++禁止变长数组'vla'[-Wvla]

我的问题是:

  • 为什么编译器接受该声明?
    编译器不能只拒绝一个长度为的数组[is-no-know-at-compile-time]
    是否存在一种兼容性语法规则?

  • 标准说了什么?
    从生成的汇编代码中我看到编译器在循环中写入堆栈,就像普通数组一样,但我找不到任何关于标准行为的信息.

Lig*_*ica 10

为什么编译器接受该声明?

因为它的作者选择让它这样做.

默认情况下,GCC允许许多旧C编译器历史上接受的非标准内容.他们喜欢这种意义上的"兼容性".

标准对[它]说了什么?

确切地说,警告说明了它:ISO C++禁止可变长度数组.

C++没有VLA.

如果你看到一个被接受,它是一个编译器扩展; 要了解编译器如何实现这样的扩展,您必须询问编译器的作者(或检查其来源,如果适用).

  • "禁止"有点强烈.通常,该标准不禁止扩展.只要实现正确处理正确形成的程序和问题*required*diagnostics,它就是一个兼容的实现.如果实现还为cetain不正确的程序提供了可重现的行为,那么它仍然符合要求; 标准并不关心形成不良的程序. (2认同)

Pet*_*ker 5

该标准要求符合标准的编译器在遇到非法内容时必须“发出诊断”。完成此操作后,可以自由地继续编译具有特定于实现的含义的代码。(请注意,“具有特定于实现的含义”是“具有未定义行为”的礼貌形式)。