C中堆栈上的动态数组分配

use*_*509 8 c c99 variable-length-array c11

我昨天刚做了一个实验,发现一些令人困惑的事情:

#include <stdio.h>

int main()
{
    int j;
    scanf("%d",&j);
    const int i = j;
    int arr[i];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

j从键盘读取数字,它用于arr在堆栈上分配数组.

编译器在编译时甚至不知道数组的大小(将j初始化为0?),但没有编译错误.这怎么可能?

小智 13

可变长度阵列被添加到C99.它在C99理论中描述:

6.7.5.2数组声明符

C99添加了一种称为可变长度数组类型的新数组类型.无法声明其大小仅在执行时已知的数组通常被认为是使用C作为数值计算语言的主要威慑.采用一些标准的执行时间阵列概念被认为对C在数值计算领域的接受至关重要.

在可变长度数组类型的声明中指定的元素数是运行时表达式.在C99之前,此大小表达式必须是整数常量表达式.

没有"堆栈上的动态数组分配".必须在声明中指定数组大小.

一些编译器,如GCC允许它们作为C90(在GCC中,这相当于ansi和C89)模式和C++的扩展.在这些情况下,您将收到警告(-Wpedantic)或错误(-Werror-pedantic-errors).请参阅编译器的文档.

Per @ Deduplicator的评论,你似乎有一种误解.可变长度数组不能声明为静态.

§6.7.6.2

10 EXAMPLE 4可变修改(VM)类型的所有声明都必须在块范围或函数原型范围内.与声明的阵列对象_Thread_local,staticextern 存储类说明不能有一个可变长度数组(VLA)型.但是,使用static存储类说明符声明的对象可以具有VM类型(即指向VLA类型的指针).最后,使用VM类型声明的所有标识符必须是普通标识符,因此不能是成员ostructures或联合.

这意味着static存储和automatic存储是互斥的.


Vla*_*cow 0

C 具有可变长度数组这样的功能。可以在飞行中定义具有自动存储持续时间的数组。