When are variable length arrays permissible?

I'm not an expert in C ++, but as far as I know, this code should fail because size not 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 it with gcc (better to say g ++)?

 ./test 7 7 /test 2 2 
+4
source share
7 answers

To allocate memory from the stack or heap for a variable, the size of the variable must be known. C ++ compilers can decide for themselves how they allocate memory, but C ++ made public how they expect C ++ compilers to handle the situation, and therefore C ++ std requires compilers to sell their memory. This happens through the sizeof statement. This operator is fully computed at compile time. The limitation of compilation time for array sizes comes from this requirement.

 int arr[10]; std::cout << sizeof(arr) << std::endl 

since each variable and type supports sizeof, their sizes must be computed at compile time in C ++. Thus, variable length arrays are not possible in C ++.

There is another very important limitation arising from this requirement. In principle, C ++ compilers could calculate the maximum amount of memory needed for a C ++ program stack if there wasn’t one problem: for recursive functions, you cannot calculate the stack size used by the program, but for everything else, the stack size can be calculated as follows way:

  • use sizeof (a) for each variable in the frame stack
  • sum the sizes of the variables to get the amount of memory needed for this stack frame
  • list all possible frames of the stack and calculate their sizes
  • Choose the largest call stack
  • select this size as the size of your program stack.

Unfortunately, recursive functions violate the whole scheme. And you need a global analysis of the flow of programs to determine which functions have infinite call stacks. But the limitation for the sizeof size operator is important, or our C ++ programs randomly run out of stack space, causing crashes and instability. And that is unacceptable. Thus, each variable and type supports the size size compile-time statement.

VLA support requires that compilers can generate code in which offsets are usually generated, since the constants for the resulting machine code actually change at run time. Standard compatible C ++ compilers usually do not have the ability to do this. C decided to add this support, and thus C compilers can do this. But in this process, they needed to break the sizeof operator. Compilation sizes can no longer be calculated. VLA support, as stated in the C standard, has big problems:

  • you cannot put a vla inside a structure or class
  • VLAs are mostly limited to local function scope

These problems have already been resolved in C ++ via std :: vector, which do not have any of these problems.

+5
source

The following is a list of new features in C99 that adds variable-length arrays .

Also see $ 6.7.6.2 / 4 Declaration of the manifesto N1548 (ISO / IEC 9899: 201x Draft Committee - December 2, 2010 N1548), which describes it in detail.

+3
source

This is a non-standard GCC extension - other compilers, such as Visual C ++, do not support this.

+2
source

This is a C99 function that allows you to declare such arrays on the stack.

+1
source

c99 supports variable length arrays ( VLA ), but neither c90 nor C ++ supports variable length arrays, but gcc supports this as an extension in both C and C ++, you can see this more clearly if you compile these arguments:

 gcc -std=c89 -pedantic 

this will give you the following warning:

 warning: ISO C90 forbids variable length array 'array' [-Wvla] 

or using g++ :

 g++ -pedantic 

will give you the following warning:

 warning: ISO C++ forbids variable length array 'array' [-Wvla] 

this standards section in the gcc manual is described in more detail. It is important to note that starting with standard variable length arrays 2011 C ( VLA ) is now optional.

+1
source

Even without VLA extensions, code can compile when the compiler was unable to determine that the dimension expression is unknown at compile time. This is still UB.

0
source

Because you are not calling g ++ as a C ++ compiler. If I try, I will get a warning stating clearly that "ISO C ++ prohibits a variable-length array." But my makefiles include the -std=c++98 option, at least when I want to compile portable C ++.

0
source

All Articles