naeg
naeg

Reputation: 4002

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

Upvotes: 5

Views: 5097

Answers (7)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158459

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

gcc -std=c89 -pedantic

this will give you the following warning:

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

or with g++:

g++ -pedantic

will give you this warning:

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

this standards section in the gcc manual goes into more details. Important to note that as of the 2011 C standard variable length arrays(VLA) are now optional.

Upvotes: 1

tp1
tp1

Reputation: 288

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.

Upvotes: 5

dubnde
dubnde

Reputation: 4441

Here is a list of new features in C99 which adds variable length arrays.

Also see $6.7.6.2/4 Array declarators of N1548(ISO/IEC 9899:201x Committee Draft — December 2, 2010 N1548) which details it.

Upvotes: 3

sharptooth
sharptooth

Reputation: 170489

That's a non-standard GCC extension - other compilers like Visual C++ don't support that.

Upvotes: 2

James Kanze
James Kanze

Reputation: 153909

Because you don't invoke g++ as a C++ compiler. If I try it, I get a warning, stating clearly that "ISO C++ forbids variable length array". But my makefiles include the option -std=c++98, at least when I want to compile portable C++.

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385108

Even without VLA extensions, the code can compile when the compiler has failed to deduce that the dimension expression is not known at compile-time. It's still UB.

Upvotes: 0

cnicutar
cnicutar

Reputation: 182619

It's a C99 feature that allows you to declare arrays like that on the stack.

Upvotes: 1

Related Questions