为什么数组没有形成

why is array not getting formed?

本文关键字:数组 为什么      更新时间:2023-10-16

为什么当我定义一个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++数组不能使用在编译时未知值的变量来定义,但是,它在函数中是如何工作的?

默认情况下,如果未指定严格的标准合规性,编译器通常允许在C++中使用 C 功能(反之亦然)。GCC 和 Clang 都允许默认使用这样的 C99 功能,即 VLA。(Visual Studio,OTOH,即使在C模式下也不支持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]

C++11 允许这样做:

#include <iostream>
constexpr int i[] = {1,2,3,4};
float k[i[2]];
int main()
{
  std::cout << sizeof(k) << "n";
}

它会很好地形成。

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