什么时候可变长度数组合法? [英] When are variable-length arrays legal?
问题描述
我不是一个C ++专家,但据我知道这个代码应该失败,因为 size
不是常数:
#include< iostream>
using namespace std;
int main(int argc,char ** argv)
{
int size = * argv [1] - 48;
char array [size];
cout<< sizeof(array)<< endl;
return 0;为什么当我用gcc(更好地说g ++)编译它时,它的工作原理:
}
。
./ test 7
7
/ test 2
2
要从堆栈或堆中为变量分配内存,需要知道。 C ++编译器可以自己决定它们如何分配内存,但是c ++已经公开了他们希望c ++编译器处理这种情况,因此c ++ std要求编译器供应商发布它们的内存处理。这通过sizeof运算符发生。此运算符在编译期完全计算。数组大小的编译时限制来自此要求。
int arr [10];
std :: cout<< sizeof(arr)< std :: endl
因为每个变量和类型都支持sizeof,时间在c ++。因此,可变长度数组在c ++中是不可能的。
这个需求有另一个非常重要的限制。原则上,c ++编译器供应商可以计算c ++程序栈所需的最大内存量,如果没有一个问题:对于递归函数,不能计算程序使用的堆栈大小,但对于其他一切,堆栈的大小可以通过执行以下操作计算:
- 对堆栈框架中的每个变量使用sizeof(a)
- 列出所有可能的堆栈框架并计算它们的大小
- 选择
- 你不能将VLA放在结构或类中
- VLA基本上局限于局部函数范围
- use sizeof(a) for every variable in stack frame
- sum the sizes of the variables to get amount of memory required for that stack frame
- list all possible stack frames and calculate their sizes
- Pick the call stack that has largest size
- choose that size as the size of your program's stack.
- you cannot put VLA inside a struct or class
- VLA's are basically restricted to the local function scope
>不幸的是,递归函数打破了整个方案。它需要全局程序的流分析来识别哪些函数可能有无限调用堆栈。但是编译时sizeof运算符的限制是重要的,否则我们的c ++程序会随机运行堆栈空间,导致崩溃和不稳定。这是不可接受的。因此,每个变量和类型都支持编译时sizeof运算符。
VLA支持要求编译器可以生成代码,通常生成的代码作为常量生成的机器代码实际上是可修改的在运行时。标准符合的C ++编译器通常没有能力做到这一点。 C决定添加这个支持,因此C编译器可以做到。但在这个过程中,他们需要打破操作员的规模。不再能够在编译时计算大小。 VLA支持在C标准中指定有很大的问题:
这些问题已经通过std :: vector没有任何这些问题。
I'm not a C++ expert, but as far as I know this code should fail due to size
not being constant:
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
int size = *argv[1] - 48;
char array [size];
cout<<sizeof(array)<<endl;
return 0;
}
Why does this work when I compile that with gcc (better say g++)?
./test 7
7
/test 2
2
To allocate memory from stack or heap for a variable, the size of the variable need to be known. C++ compilers can decide themselves how they allocate memory, but c++ has made it public how they expect c++ compilers to handle the situation, and thus c++ std requires that compiler vendors publish their memory handling. This happens via sizeof operator. This operator is calculated completely in compile-time. The compile-time restriction for the array sizes comes from this requirement.
int arr[10];
std::cout << sizeof(arr) << std::endl
since every variable and type supports sizeof, their sizes need to be calculated on compile-time in c++. Thus variable-length arrays are impossible in c++.
There is another very important restriction flowing from this requirement. In principle c++ compiler vendors could calculate maximum amount of memory required for c++ program's stack, if only there weren't one problem: for recursive functions, you cannot calculate stack size used by the program, but for everything else, the size of stack can be calculated by doing the following:
Unfortunately, recursive functions break the whole scheme. And it would need global program's flow analysis to regognize which functions have possibly infinite call stacks. But the limitation for compile-time sizeof operator is important or our c++ programs would randomly run out of stack space, causing crashes and unstability. And this is unacceptable. Thus every variable and type supports compile-time sizeof operator.
VLA support requires that compilers can generate code where offsets normally generated to as constants to the resulting machine code are actually modifiable on runtime. Standard conforming c++ compilers normally do not have ability to do this. C decided to add this support and thus C compilers can do it. But in the process they needed to break the sizeof operator. No longer can the sizes be calculated on compile-time. VLA support as specified in the C standard has big problems:
These problems were already solved in c++ via std::vector which do not have any of these problems.
这篇关于什么时候可变长度数组合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!