2

Variable length arrays are supported in C:

int main(){
   int num = 5;
    int arr[num];
    return 0;
}

I understand that arr is allocated during runtime. How is this accomplished? Does it call a C runtime function to allocate the byes? As the allocation amount is not known during compile time hence instructions should not exist for stack allocation.

As a side question, is it good practice to use them over malloc and heap allocation, as VLAs are not officially supported in C++?

Edit:

Seems like it may be implemented using alloca which allocates on the stack frame.

Community
  • 1
  • 1
  • VLAs are also "only" optionally supported in C11 (meaning not all C11 compliant compilers need to support it) – UnholySheep Apr 21 '20 at 17:38
  • In your example the allocation amount is known at compile time, when `arr` is allocated `num` can only ever be 5. But you could `scanf("%d", &num);` to make it unknown. – Schwern Apr 21 '20 at 17:40
  • And possibly relevant is: https://stackoverflow.com/questions/21182307/how-does-gcc-implement-variable-length-arrays – UnholySheep Apr 21 '20 at 17:41

3 Answers3

3

How VLA allocation is accomplished is up to the individual implementation - the ones I'm familiar with allocate from the stack, but they don't have to.

VLAs are useful, but only in very limited circumstances. Since their size isn't known until runtime, they can't be members of struct types, they can't have static storage durations, and their sizes may be limited. If you need temporary storage that isn't too big (on the order of a few kilobytes or so) and you don't know how big it is ahead of time and it doesn't need to persist beyond the current scope, then VLAs can be handy and are easier to deal with than dynamic memory.

However, as of 2011 VLA support is optional, so I wouldn't come to rely on them too heavily.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Because it existed first, I've tended to use `alloca.h` et. al. because I usually only need a 1D array and it's more compatible with `malloc` if I have to switch later on because the size will no longer fit [well] on the stack. But, just curious, what is/was the rationale for changing VLA support to optional? – Craig Estey Apr 21 '20 at 17:50
  • @CraigEstey: I think they cause problems in embedded environments, where stack space is limited. – John Bode Apr 21 '20 at 17:58
0

Not only, as you correctly say

VLAs are not officially supported in C++.

but they also were relegated to "optional feature" since C11 (though they were added only in C99!). This is actually a reason for not using them, in the purpose of having portable code.


Its memory allocation details are unfortunately implementation dependant. They are are usually allocated in the stack by most compilers as automatic storage variables (according to my reasearch and to my personal experience), but can also be allocated in the heap.

Having arrays allocated in the stack can lead to stack overflow issues, especially in embedded environment. I suggest visiting this question (about VLAs not being supported in C++ standards); in particular, it is really interesting this answer, by @Quuxplusone (enphasis is mine):

Variable-length arrays in C99 were basically a misstep. In order to support VLAs, C99 had to make the [...] concessions to common sense.

Less importantly in the C++ world, but extremely important for C's target audience of embedded-systems programmers, declaring a VLA means chomping an arbitrarily large chunk of your stack. This is a guaranteed stack-overflow and crash. (Anytime you declare int A[n], you're implicitly asserting that you have 2GB of stack to spare. After all, if you know "n is definitely less than 1000 here", then you would just declare int A[1000].


As far as I can see, their main advantage is having arrays of variable length with local scope, something that cannot be achieved with its alternatives:

/* Fixed length array, either global or local */
int arr[100];

/* Dynamic allocation */
int * arr = malloc (100 * sizeof (int));

In most cases, anyway, the developer either

  • Knows what is the maximum size that VLA can have. So why not allocating it statically with a fixed length?
  • Has no control on the maximum size, so they will have to perform a sanity check to avoid stack overflows. So why not limiting its size with a fixed length allocation?
Community
  • 1
  • 1
Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
0

As a side question, is it good practice to use them over malloc and heap allocation,

No, consider instead using flexible array members as the last member of your variable-sized struct-s. Check that malloc did not fail at runtime.

In embedded programming, VLA-s are useful when you can guarantee that they are small enough since you don't want to blow up your call stack. A minima precede int arr[num]; with something like assert(num>0 && num<100); or better yet, add such a check at runtime. You could use tools like Frama-C to prove that statically.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547