为什么在我定义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 ++中,无法使用在编译时未知其值的变量来定义数组,但仍然如此,那么它在函数中是如何工作的?)
答案 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 ++扩展。