Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
328 views
in Technique[技术] by (71.8m points)

c++ - When are variable-length arrays legal?

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

  1. use sizeof(a) for every variable in stack frame
  2. sum the sizes of the variables to get amount of memory required for that stack frame
  3. list all possible stack frames and calculate their sizes
  4. Pick the call stack that has largest size
  5. choose that size as the size of your program's stack.

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:

  1. you cannot put VLA inside a struct or class
  2. VLA's are basically restricted to the local function scope

These problems were already solved in c++ via std::vector which do not have any of these problems.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...