GNU 编译器与 Visual Studio 在分配的数组上分配了长度常量,在作用域中



我知道,如果你在 c/c++ 中设置了一个动态值,你就不能在括号内使用该值来分配数组(这将使它成为所谓的可变长度数组 (VLA),当前C++标准不支持)......

即参见:
C++ : 可变长度数组

http://en.wikipedia.org/wiki/Variable-length_array

不太明白(以及我在这里没有看到确切的问题)是为什么GNU c/c ++编译器(gccg++)可以使用基于整数值的动态分配(据我所知),只要该值是数组分配范围内的常量,但是Visual Studio不支持这一点,并且会拒绝编译代码, 吐出错误。

例如在g++

void Foo(const unsigned int bar)
{
  double myStuff[bar];
  //... do stuff...
}

。编译就好了...

但是相同的代码拒绝在我使用的 VS 版本中编译,除非我传递给 bar 的任何内容在所有范围内都const,或者是#definestatic const等。

我怀疑也许 GNU 编译器使用该范围来推断该值是该范围内的常量,并且要么简单地将其分配给 malloc 或以某种方式专门处理它。

我的问题是:

  1. 谁(VS或GNU)在他们如何方面更接近标准处理这个?
  2. 有没有办法在范围内使用[]值来执行此 VS,但不会在整个程序中全局const而无需malloc调用?
  3. 如果我在我的GNU 编译的代码?

语言的角度来看,VLA 仅在 C 中受支持,并且仅从 C99 开始支持。 它们在C++中不受支持。

编译器的角度来看,g++ 将支持 VLA 作为 C90 和 C++ 的扩展,但如果使用 -pedantic 进行编译,它将禁用这些扩展,并且会出现编译错误。

Visual Studio在C或C++中根本不支持VLA。 VS最多只支持C89标准,AFAIK MS根本没有计划支持后来的C标准。

就范围而言,这是在C标准中定义的:

6.7.6.2 数组声明符
...
2 如果标识符被声明为具有可变修改的类型,则该标识符应为普通标识符标识符(如 6.2.3 中所定义),没有链接,并且具有块范围或功能原型范围。如果标识符声明为具有静态或线程存储的对象持续时间,它不应具有可变长度数组类型。

VLA 不能static或文件范围内声明是有技术原因的;具有静态存储持续时间的对象在程序启动时分配并一直保留到程序终止,如果我没记错的话,不能保证对象将以任何特定顺序分配和初始化。 因此,这些项需要在编译时知道它们的大小。

GNU编译器集合支持可变长度数组作为扩展,使用-pedantic编译,您将看到预期的警告。

#include <iostream>
int main()
{
    int foo = 10;
    int bar[foo];
}

编译:

g++-4.8 -std=c++11 -O2 -pedantic -pthread main.cpp && ./a.out
main.cpp: In function ‘int main()’:
main.cpp:6:16: warning: ISO C++ forbids variable length array ‘bar’ [-Wvla]
     int bar[foo];
                ^

最新更新