为什么阵列没有形成?

时间:2012-06-07 07:31:26

标签: c++ arrays const

为什么在我定义array of floats时会这样:

const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // Illegal

在任何功能之外(即在全球范围内),这样做是违法的。 如果我在任何函数(包括main())中执行相同的操作,例如:

void f() {
    const int i[] = { 1, 2, 3, 4 };
    float f[i[3]];
    cout << sizeof(f);
}

main()
{
    f();
}

然后一切正常,它成功输出16的大小。 为什么会有这种差异?是因为存储位置从静态(最初)到堆栈的变化?

(PS:我知道在C ++中,无法使用在编译时未知其值的变量来定义数组,但仍然如此,那么它在函数中是如何工作的?)

2 个答案:

答案 0 :(得分:3)

默认情况下,如果未指定严格的标准合规性,则编译器通常允许在C ++中使用C功能(反之亦然)。 GCC和Clang都允许默认使用这样的C99特性,即VLA。 (即使在C模式下,Visual Studio,OTOH也不支持VLA。)但是,请注意,只能在块范围内定义VLA。

  

6.7.6.2数组声明符

     

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

因此,全局VLA在C ++中不起作用(使用松散的编译器设置),而本地VLA则起作用。

尝试编译以下内容

$ cat float.cpp
int main() {
  int i = 2;
  const float f[i] = { 1, 2 };
}

g++ -std=c++98 -Wall -ansi -pedantic float.cpp,你会得到类似的内容:

float.cpp: In function 'int main()':
float.cpp:3:18: warning: ISO C++ forbids variable length array 'f' [-Wvla]
float.cpp:3:29: error: variable-sized object 'f' may not be initialized
float.cpp:3:15: warning: unused variable 'f' [-Wunused-variable]

答案 1 :(得分:2)

C ++ 11允许这样:

#include <iostream>

constexpr int i[] = {1,2,3,4};
float k[i[2]];

int main()
{
  std::cout << sizeof(k) << "\n";
}

它会很好地形成。

至于最初的问题,这可能是G ++扩展。