C+中的可变长度数组(VLA)+;编译程序 正如我们已经知道的,(C99中的标准化)不是C++中的标准的一部分。

C+中的可变长度数组(VLA)+;编译程序 正如我们已经知道的,(C99中的标准化)不是C++中的标准的一部分。,c++,dynamic-arrays,C++,Dynamic Arrays,因此,下面的代码在C++中是“非法的”: void foo(int n){ int vla[n]; 对于(int i=0;i

因此,下面的代码在C++中是“非法的”:

void foo(int n){
int vla[n];
对于(int i=0;i

尽管如此,编译器(g++和clang++)还是接受代码作为有效语法,在启用
-pedantic
标志时只会产生警告

ISO-C++禁止可变长度数组'VLA’[Wvla ] < /P> 我的问题是:

  • 为什么编译器接受这个声明
    编译器不能仅仅拒绝长度
    [编译时不知道]
    的数组
    是否有某种兼容性语法规则可遵循

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

为什么编译器接受这个声明

因为它的作者选择了这样做

默认情况下,GCC特别允许许多非标准的东西,这些东西在历史上被旧的C编译器所接受。他们喜欢这种意义上的“兼容性”

标准对[它]有什么规定

<>这正是它所说的警告:ISO C++禁止可变长度数组。< /P> C++没有VLA。


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

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

您提出了两个问题,而不是一个。编译器扩展就是这样。扩展。“在启用
-pedantic
标志的情况下仅生成警告。”-这就是所有
-pedantic
承诺<代码>-学究式错误
会导致这些错误。请使用全名,而不是首字母缩写。它对整个社区更有用,但并不总是如此professional@JacekCz谢谢你的建议,我已经编辑过了,“禁止”有点强。一般来说,本标准不禁止扩展。只要实现正确地处理格式正确的程序和所需的诊断问题,它就是一个兼容的实现。如果实现还为格式错误的程序提供了可复制的行为,那么它仍然是合规的;标准不关心格式错误的程序。@我告诉GCC开发人员!“标准不关心格式不正确的程序”,它确实如此!这并不意味着他们不能通过翻译。这种“允许延期”都源于宽大。我的声明与gcc的行为有什么不同?我认为宽大处理是完全恰当的;它允许编译器实现和测试对语言提出的添加,这是gcc和clang开发人员都要做的。(标准如何表达对不合格程序的关注?它足以标记为不正确的形式和明确地不定义他们的行为。)@ RICI:警告消息说“ISO C++禁止可变长度数组”。您说“标准不禁止扩展”。如果不深入研究基本的阅读理解,我无法进一步阐述这两种说法的区别,我相信你不需要:)“标准如何表达对格式错误程序的关注?只需将其标记为格式错误,并明确不定义其行为即可。”是的,这就是它表达其关切的方式。如果它不在乎,它甚至不会提到它们。可能不完全是“未定义的行为”:@nobar——标准没有说明代码的功能,也不要求实现记录它的功能。这是“未定义的行为”。没错。如果有UB,并且编译器决定准确地记录它在这种情况下发出的代码,它将有效地转变为该平台上的实现定义行为:您可以在此平台上安全地使用它,但代码将不再可移植到其他平台。就像您依赖于
sizeof(int)==4
一样。
void foo(int n) {
  int vla[n];
  for (int i = 0; i < n; ++i) {
    vla[i] = i;
  }
}