GCC如何分配静态运行的数组长度
How does gcc allocate statically run time known length of array
我写了以下代码:
int tester(int n)
{
int arr[n];
// ...
}
使用g 编译了此代码,没有警告。
我的问题是 - 如何?参数n仅在运行时已知,在数组中是静态分配的。GCC如何编译?
这是GCC为C 提供的扩展名,尽管C99自C99以来,C均适当地支持了可变长度数组(" VLAS")。
实施并不难;在典型的呼叫堆栈实现中,该功能只需要保存堆栈框架的底座,然后通过动态指定的金额推进堆栈指针。VLA总是提出警告:如果数字太大,您会得到不确定的行为(在堆栈溢出中表现出来),这使它们比std::vector
。
在某个时候努力为C 添加类似的功能,但是事实证明,对于类型系统而言,这非常困难(例如,arr
的类型是什么?如何在功能模板中推导它?)。这些问题在C中的可见程度较低,C具有更简单的类型系统和对象模型(但是,您仍然可以说,C的情况更糟,因为拥有VLA,标准的很大一部分都花在它们上,并且语言将会没有它们,它变得更简单,不一定要差)。
gnu c库提供了一个函数,可以在堆栈中分配内存-Alloca(3)。它只是减少了堆栈指针,从而在其上创建了一些划痕空间。GCC使用alloca(3)
实现C99可变长度数组 - 它首先减少函数序列中的堆栈指针,以为所有自动变量创建空间,该变量在编译时已知,然后使用alloca(3)
进一步降低它并为arr
提供空间在运行时确定的大小。优化器实际上可能融合了两个减小。
int tester(int n)
{
int arr[n];
return 0;
}
编译成
;; Function tester (tester)
tester (int n)
{
int arr[0:D.1602D.1602] [value-expr: *arr.1];
int[0:D.1602D.1602] * arr.1;
long unsigned int D.1610D.1610;
int n.0;
...
<bb 2>:
n.0 = n;
...
D.1609D.1609 = (long unsigned int) n.0;
D.1610D.1610 = D.1609D.1609 * 4;
D.1612D.1612 = __builtin_alloca (D.1610D.1610); <----- arr is allocated here
arr.1 = (int[0:D.1602D.1602] *) D.1612D.1612;
...
等效于以下C代码:
int tester(int n)
{
int *arr = __builtin_alloca(n * sizeof(int));
return 0;
}
__builtin_alloca()
是GCC的内部实现alloca(3)
。
相关文章:
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 代码使用向量成功运行,但使用数组显示错误
- 给定一个整数数组,需要在Max_Heap上运行操作。得到错误"segmentation fault",有什么想法吗?(C++)
- 在 c++ 中是否允许创建具有运行时边界的数组?
- 运行时C++数组初始化问题
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 如何在 Visual Studio C++ 11 中运行时定义二维数组?
- 传递数组结构、ofstream 和 interger 以运行
- c++:运行一个函数 8 次,并将每个答案添加到数组或 JSON 中
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- C++ .我正在尝试通过使用开关内的数组来获取用户输入,但是当我运行代码时,它显示分段错误?
- 如何在运行时阻止数组重置
- 运行搜索数组
- 当数组大小在C++中未知时,如何在运行时将对字符串数组的引用作为函数参数传递?
- 程序在初始化期间未与数组一起运行
- 由于 2D 数组声明,C++ 14 中的运行时错误
- 为什么C++允许在运行时将数组大小传递给函数以构造固定大小的数组?
- 在函数中创建的数组,编译时还是运行时?
- 在运行时 c++ 更改用类对象填充的数组的大小
- 尝试运行数组strcpy程序时需要帮助