Question

I heard from many people that variable length array, introduced in C99, are terrible. Some guys on IRC said a minute ago « I don't think C++ will get VLA's, strousoup made some very negative comments about them ».

What are the reasons why those people hate VLAs?

Was it helpful?

Solution

VLAs allocate arrays on the stack, in runtime, making it harder, or even impossible to determine the stack size used at compile time. Since the stack has a rather small amount of memory available (in comparison with the heap), many worry that VLAs have a great potential for stack overflow.

The upcoming version of the MISRA-C coding standard is most likely going to ban VLAs as well.

OTHER TIPS

Although variable-length arrays have their problems, one should keep in mind how they came to be: As a replacement for alloca(), which is arguably even more problematic.

While it was trivial to implement on the PDP-11, this was not the case on other architectures and Ritchie and Thompson removed it from their implementation.

However, variably-sized automatic allocation was apparently useful enough that alloca() got resurrected despite it's problems (in particular, it can't be used everywhere where arbitrary function calls would be possible and on many architectures it must be a compiler built-in anyway). The C working group agreed with providing such a feature, but thought variable-length arrays the superior solution.

If you look at the features added with C99 (complex numbers, type-generic math, restrict, ...), you should notice that a lot of them are geared towards making C a better language for numeric computation. Variable-length arrays are useful there as well and I believe Fortran already had them at that time. Furthermore, their introduction also led to variably-modified derived types (eg pointers to variably-sized arrays), which are particularly useful when dealing with matrices.

As others have pointed out, VLAs make it really easy to overflow your stack frame. I'm not a compiler writer, but my understanding is that VLAs can also be a bugger to support (they are now optional in C2011). And their use is limited to block or function scope; you cannot use a VLA at file scope, and they can't have external linkage.

I wouldn't want to see VLA syntax go away, though; it comes in really handy when dynamically allocating multi-dimensional arrays where the inner dimensions are not known until runtime, such as:

size_t r, c;
// get values for r and c
int (*arr)[c] = malloc(r * sizeof *arr);
if (arr)
{
   ...
   arr[i][j] = ...;
   ...
   free(arr);
}

One contiguous allocation (and one corresponding free), and I can subscript it as a 2D array. The alternatives usually mean piecemeal allocation:

size_t r, c;
...
int **arr = malloc(sizeof *arr * r);
if (arr)
{
  for (i = 0; i < c; i++)
    arr[i] = malloc(sizeof *arr[i] * c);
  ...
  arr[i][j] = ...;
  ...
  for (i = 0; i < c; i++)
    free(arr[i]);
  free(arr);
}

or using 1-d offsets:

int *arr = malloc(sizeof *arr * r * c);
if (arr)
{
  ...
  arr[i * r + j] = ...;
  ...
  free(arr);
}

VLAs make it much easier to overflow the stack. In most places where you would use a VLA, you would base the length on one of the functions parameters. If the parameter is something you don't expect, you could end up allocating a very large array on the stack. Unless you can be sure that no combination of arguments can cause you to overflow the stack, you should use dynamic allocation.

One place it might make sense to use them is on embedded platforms, since when doing embedded programming is one of the few situations where you are likely to keep track of your memory usage closely enough to be sure that you won't have a stack overflow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top