1

为什么当我定义一个array of floatslike 时:

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++ 中,不能使用在编译时其值未知的变量来定义数组,但仍然如此,那么它在函数中是如何工作的?)

4

2 回答 2

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]
于 2012-06-07T07:42:57.437 回答
2

C++11 允许这样做:

#include <iostream>

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

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

它会很好地形成。

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

于 2012-06-07T07:41:46.690 回答