Categories
arrays c++ standards variable-length variable-length-array

Why aren’t variable-length arrays part of the C++ standard?

426

I haven’t used C very much in the last few years. When I read this question today I came across some C syntax which I wasn’t familiar with.

Apparently in C99 the following syntax is valid:

void foo(int n) {
    int values[n]; //Declare a variable length array
}

This seems like a pretty useful feature. Was there ever a discussion about adding it to the C++ standard, and if so, why it was omitted?

Some potential reasons:

  • Hairy for compiler vendors to implement
  • Incompatible with some other part of the standard
  • Functionality can be emulated with other C++ constructs

The C++ standard states that array size must be a constant expression (8.3.4.1).

Yes, of course I realize that in the toy example one could use std::vector<int> values(m);, but this allocates memory from the heap and not the stack. And if I want a multidimensional array like:

void foo(int x, int y, int z) {
    int values[x][y][z]; // Declare a variable length array
}

the vector version becomes pretty clumsy:

void foo(int x, int y, int z) {
    vector< vector< vector<int> > > values( /* Really painful expression here. */);
}

The slices, rows and columns will also potentially be spread all over memory.

Looking at the discussion at comp.std.c++ it’s clear that this question is pretty controversial with some very heavyweight names on both sides of the argument. It’s certainly not obvious that a std::vector is always a better solution.

13

  • 6

    Just out of curiosity, why does it need to be allocated on the stack? Are you that affraid of heap allocation performance issues?

    Dec 11, 2009 at 10:32

  • 50

    @Dimitri Not really, but there’s no denying that stack allocation will be faster than heap allocation. And in some cases this may matter.

    Dec 11, 2009 at 10:37

  • 17

    The main advantage of variable length arrays that all data is close together so when you iterate through this array you read and write bytes next to each other. Your data is fetched into the cache and cpu can work on it without fetching and sending the bytes to/from the memory.

    – Calmarius

    Oct 24, 2010 at 16:04

  • 5

    Variable length arrays are also may be used to replace preprocessor constants with static const variables. Also in C you don’t have another options for VLA, and it is sometimes needed to write portable C/C++ code (compatible with both compilers).

    – Yury

    Dec 21, 2012 at 6:45

  • 3

    as an aside, it appears clang++ allows VLAs.

    Mar 16, 2014 at 20:42

242

There recently was a discussion about this kicked off in usenet: Why no VLAs in C++0x.

I agree with those people that seem to agree that having to create a potential large array on the stack, which usually has only little space available, isn’t good. The argument is, if you know the size beforehand, you can use a static array. And if you don’t know the size beforehand, you will write unsafe code.

C99 VLAs could provide a small benefit of being able to create small arrays without wasting space or calling constructors for unused elements, but they will introduce rather large changes to the type system (you need to be able to specify types depending on runtime values – this does not yet exist in current C++, except for new operator type-specifiers, but they are treated specially, so that the runtime-ness doesn’t escape the scope of the new operator).

You can use std::vector, but it is not quite the same, as it uses dynamic memory, and making it use one’s own stack-allocator isn’t exactly easy (alignment is an issue, too). It also doesn’t solve the same problem, because a vector is a resizable container, whereas VLAs are fixed-size. The C++ Dynamic Array proposal is intended to introduce a library based solution, as alternative to a language based VLA. However, it’s not going to be part of C++0x, as far as I know.

20

  • 32

    +1 and accepted. One comment though, I think the safety argument is a little bit weak since there are so many other ways to cause stack overflows. The safety argument could be used to support the position that you should never use recursion and that you should allocate all objects from the heap.

    Dec 11, 2009 at 10:46

  • 23

    So you’re saying that because there are other ways to cause stack overflows, we might as well encourage more of them?

    – jalf

    Dec 11, 2009 at 10:57

  • 3

    @Andreas, agreed about the weakness. But for recursion, it takes a huge number of calls until stack is eaten up, and if that can be the case, people would use iteration. As some people on the usenet thread say, though, this is not an argument against VLAs in all cases, since sometimes you definitely may know an upper bound. But in those cases, from what i see a static array can equally be sufficient, since it would not waste much space anyway (if it would, then you would actually have to ask whether the stack area is large enough again).

    Dec 11, 2009 at 11:00

  • 11

    Also look at Matt Austern’s answer in that thread: The language specification of VLAs would probably considerably more complex for C++, because of the stricter type matches in C++ (example: C allows assigning a T(*)[] to a T(*)[N] – in C++ this is not allowed, since C++ does not know about “type compatibility” – it requires exact matches), type parameters, exceptions, con- and destructors and stuffs. I’m not sure whether the benefits of VLAs would really pay off all that work. But then, i have never used VLAs in real life, so i probably don’t know good use cases for them.

    Dec 11, 2009 at 11:03

  • 1

    @AHelps: Perhaps what would be best for that would be a type that behaves somewhat like vector but requires a fixed LIFO usage pattern and maintains one or more per-thread statically-allocated buffers which are generally sized according to the largest total allocation the thread has ever used, but which could be explicitly trimmed. A normal “allocation” would in the common case require nothing more than a pointer copy, pointer-from-pointer subtraction, integer comparison, and pointer addition; de-allocation would simply require a pointer copy. Not much slower than a VLA.

    – supercat

    Jun 3, 2015 at 16:15

242

There recently was a discussion about this kicked off in usenet: Why no VLAs in C++0x.

I agree with those people that seem to agree that having to create a potential large array on the stack, which usually has only little space available, isn’t good. The argument is, if you know the size beforehand, you can use a static array. And if you don’t know the size beforehand, you will write unsafe code.

C99 VLAs could provide a small benefit of being able to create small arrays without wasting space or calling constructors for unused elements, but they will introduce rather large changes to the type system (you need to be able to specify types depending on runtime values – this does not yet exist in current C++, except for new operator type-specifiers, but they are treated specially, so that the runtime-ness doesn’t escape the scope of the new operator).

You can use std::vector, but it is not quite the same, as it uses dynamic memory, and making it use one’s own stack-allocator isn’t exactly easy (alignment is an issue, too). It also doesn’t solve the same problem, because a vector is a resizable container, whereas VLAs are fixed-size. The C++ Dynamic Array proposal is intended to introduce a library based solution, as alternative to a language based VLA. However, it’s not going to be part of C++0x, as far as I know.

20

  • 32

    +1 and accepted. One comment though, I think the safety argument is a little bit weak since there are so many other ways to cause stack overflows. The safety argument could be used to support the position that you should never use recursion and that you should allocate all objects from the heap.

    Dec 11, 2009 at 10:46

  • 23

    So you’re saying that because there are other ways to cause stack overflows, we might as well encourage more of them?

    – jalf

    Dec 11, 2009 at 10:57

  • 3

    @Andreas, agreed about the weakness. But for recursion, it takes a huge number of calls until stack is eaten up, and if that can be the case, people would use iteration. As some people on the usenet thread say, though, this is not an argument against VLAs in all cases, since sometimes you definitely may know an upper bound. But in those cases, from what i see a static array can equally be sufficient, since it would not waste much space anyway (if it would, then you would actually have to ask whether the stack area is large enough again).

    Dec 11, 2009 at 11:00

  • 11

    Also look at Matt Austern’s answer in that thread: The language specification of VLAs would probably considerably more complex for C++, because of the stricter type matches in C++ (example: C allows assigning a T(*)[] to a T(*)[N] – in C++ this is not allowed, since C++ does not know about “type compatibility” – it requires exact matches), type parameters, exceptions, con- and destructors and stuffs. I’m not sure whether the benefits of VLAs would really pay off all that work. But then, i have never used VLAs in real life, so i probably don’t know good use cases for them.

    Dec 11, 2009 at 11:03

  • 1

    @AHelps: Perhaps what would be best for that would be a type that behaves somewhat like vector but requires a fixed LIFO usage pattern and maintains one or more per-thread statically-allocated buffers which are generally sized according to the largest total allocation the thread has ever used, but which could be explicitly trimmed. A normal “allocation” would in the common case require nothing more than a pointer copy, pointer-from-pointer subtraction, integer comparison, and pointer addition; de-allocation would simply require a pointer copy. Not much slower than a VLA.

    – supercat

    Jun 3, 2015 at 16:15

32

You could always use alloca() to allocate memory on the stack at runtime, if you wished:

void foo (int n)
{
    int *values = (int *)alloca(sizeof(int) * n);
}

Being allocated on the stack implies that it will automatically be freed when the stack unwinds.

Quick note: As mentioned in the Mac OS X man page for alloca(3), “The alloca() function is machine and compiler dependent; its use is dis-couraged.” Just so you know.

4

  • 8

    Also, the scope for alloca() is the entire function, not just the block of code containing the variable. So using it inside of a loop it will continuously increase the stack. A VLA does not have this problem.

    – sashoalm

    Jul 1, 2016 at 11:49

  • 4

    However, VLAs having the scope of the enclosing block means they are significantly less useful than alloca() with the scope of the entire function. Consider: if (!p) { p = alloca(strlen(foo)+1); strcpy(p, foo); } This cannot be done with VLAs, precisely because of their block scope.

    Jan 12, 2017 at 16:35

  • 3

    That does not answer OP’s why question. Moreover, this is a C-like solution, and not really C++-ish.

    – Adrian W

    Jun 25, 2018 at 15:37


  • not equivalent. alloca has dirty syntax.

    – CodingLab

    Dec 27, 2021 at 15:50