4

It has been a long time since I have programmed in basic compilers with basic arrays, but recently I saw an array declaration like this:

int y;
cin>>y;
int z[y];

old time compilers used to give error "Storage size of array isn't constant". Then I found out about variable size arrays in C99. I wonder how they work internally. Does that makes array dynamic? Is this memory allocated at heap? Does this binding is still done statically? If so how.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Hina
  • 113
  • 1
  • 1
  • 8
  • 3
    C++ doesn't have VLAs, sorry. The only way for what you wrote to work is to use a non standard compiler extension. – ScarletAmaranth Nov 30 '13 at 02:15
  • I dont know what I am doing wrong I am using Orwell Dev c++ compiler and my code is in a .cpp file as well. I get the point compiler allows to do that. – Hina Nov 30 '13 at 02:18
  • but still how does the binding for VLA's work, even in C – Hina Nov 30 '13 at 02:19
  • 1
    If you're using a C++ compiler, unless VLAs are supported by non-standard extension it isn't going to work. If you want something that *will* work, `std::vector z(y);`. And Erik summed it up pretty well regarding how it "works" in C99. – WhozCraig Nov 30 '13 at 02:21
  • @Hina Or wait for C++14 and type: std::dynarray<> :). – ScarletAmaranth Nov 30 '13 at 02:21
  • thanks @WhozCraig I am looking up at c99. Turbo C++ used to give error on such syntax, but Dev c++ wasnt, so ...... deducably they are using some non standard compiler extensions – Hina Nov 30 '13 at 02:30
  • @ScarletAmaranth both `gcc` and `clang` support VLA as an extension in C++ so this is a valid *C++* topic. – Shafik Yaghmour Nov 30 '13 at 02:31

3 Answers3

4

Variable Length Array(VLA)s are a C99 feature but several compilers including gcc supports VLA as an extension outside of C99 and both gcc and clang support variable length arrays in C++ as an extension even though this is really a C99 feature.

In both gcc and clang building using the -pedantic flag will produce a warning similar to the following in C:

warning: variable length arrays are a C99 feature [-Wvla-extension]

and something similar to this in C++:

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

The usual implementation will allocate VLA on the stack since they will treat them just like other automatic variables which although the standard does not refer to the stack or heap are usually allocated on the stack in most cases.

We can also see from the C99 draft standard that VLAs are just another variation of an array declaration from section 6.7.5.2 Array declarators paragraph 4 says (emphasis mine):

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

we see from paragraph 5 that it's size does not change during it's lifetime:

[...]The size of each instance of a variable length array type does not change during its lifetime.[...]

Although a major difference with VLAs and other variables is that sizeof is evaluated for VLAs while otherwise it computed at compile time, from section 6.5.3.4 The sizeof operator paragraph 2:

[...]If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
3

Does that makes array dynamic?

It depends how you define "dynamic". VLA certainly cannot grow or shrink or, in other words, change its size once it is created. It is dynamic, though, in a sense that its length is not known in compile-time.

Is this memory allocated at heap?

How the memory is allocated for the VLA is implementation specific. Generally speaking, the memory for the VLA is allocated from space in the stack frame of the caller. It is then automatically freed when the function where VLA is defined returns to its caller, or if VLA goes out of scope.

The closest relative of VLA is alloca() function, which pretty much can be considered to have the same effect, at least in C. Assuming that compiler implements the VLA the same way alloca() is implemented, you can think of these two arrays as being technically the same in C:

int *a = alloca(sizeof(int) * N);
int b[N];

The VLA has, however, more compact and convenient syntax. But most importantly, VLA by nature has an automatic storage duration and gives compiler more freedom to decide whether to destroy/free the array upon leaving the scope where it was declared, or upon returning from the function.

This becomes very important in languages such as C++ where compiler implements RAII idiom and must guarantee to destroy objects with automatic storage duration upon exiting their scope.

Note, however, that VLA is not currently a part of C++ language and is implemented by compiler as a non-standard extension. But they are expected to become standard in C++14.

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
1

Short answer: it reserves space on the stack, by incrementing the stack pointer.

Erik van Velzen
  • 6,211
  • 3
  • 23
  • 23
  • Longer answer - [it's up to the compiler](https://stackoverflow.com/q/33020346/10396), which could use the heap or stack. – AShelly Dec 05 '18 at 18:54