Variable-length array
In computer programming, a variable-length array, also called variable-sized or runtime-sized, is an array data structure whose length is determined at runtime, instead of at compile time. In the language C, the VLA is said to have a variably modified data type that depends on a value.
The main purpose of VLAs is to simplify programming of numerical algorithms.
Programming languages that support VLAs include Ada, ALGOL 68, APL, C#, COBOL, Fortran 90, J, and Object Pascal. C99 introduced support for VLAs, although they were subsequently relegated in C11 to a conditional feature, which implementations are not required to support; on some platforms, VLAs could be implemented formerly with
alloca or similar functions.Growable arrays are generally more useful than VLAs because dynamic arrays can do everything VLAs can do, and also support growing the array at run-time. For this reason, many programming languages only support growable arrays. Even in languages that support variable-length arrays, it's often recommended to avoid using variable-length arrays, and instead use dynamic arrays.
Memory
Allocation
- The GNU Compiler Collection for C allocates memory for VLAs with automatic storage duration on the stack. This is the faster and more straightforward option compared to heap-allocation, and is used by most compilers.
- VLAs can also be allocated on the heap and internally accessed using a pointer to this block.
Implementation
Ada
The following is the same example in Ada. Ada arrays carry their bounds with them, so there is no need to pass the length to the Process function.type Vals_Type is array of Float;
function Read_And_Process return Float is
Vals : Vals_Type ;
begin
for I in 1.. N loop
Vals := Read_Val;
end loop;
return Process ;
end Read_And_Process;
Fortran 90
The equivalent Fortran 90 function isfunction read_and_process result
integer,intent::n
real::o
real,dimension::vals
integer::i
do i = 1,n
vals = read_val
end do
o = process
end function read_and_process
when utilizing the Fortran 90 feature of checking procedure interfaces at compile time; on the other hand, if the functions use pre-Fortran 90 call interface, the functions must first be declared, and the array length must be explicitly passed as an argument :
function read_and_process result
integer,intent::n
real::o
real,dimension::vals
real::read_val, process
integer::i
do i = 1,n
vals = read_val
end do
o = process
end function read_and_process
C
Certain C language standards require support for variable-length arrays. Variable-length arrays were never part of the C++ language standard.The following C99 function allocates a variable-length array of a specified size, fills it with floating-point values, and then passes it to another function for processing. Because the array is declared as an automatic variable, its lifetime ends when
readAndProcess returns.float readAndProcess
In C99, the length parameter must come before the variable-length array parameter in function calls. In C11, a macro is defined if VLA is not supported. The C23 standard makes VLA types mandatory again. Only creation of VLA objects with automatic storage duration is optional. GCC had VLA as an extension before C99, one that also extends into its C++ dialect.
Linus Torvalds has expressed his displeasure in the past over VLA usage for arrays with predetermined small sizes because it generates lower quality assembly code. With the Linux 4.20 kernel, the Linux kernel is effectively VLA-free.
Although C11 does not explicitly name a size-limit for VLAs, some believe it should have the same maximum size as all other objects, i.e.
SIZE_MAX bytes. However, this should be understood in the wider context of environment and platform limits, such as the typical stack-guard page size of 4 KiB, which is many orders of magnitude smaller than SIZE_MAX.It is possible to have VLA object with dynamic storage by using a pointer to an array.
- include
- include
C++
While C++ does not support stack-allocated variable length arrays, they may be allowed by some compiler extensions such as on GCC and Clang. Otherwise, an array is instead heap-allocated, however a collection type such asstd::vector is probably better. This is because the existing collection types in C++ automatically use "resource acquisition is initialization", and will automatically de-allocate once going out of scope.int* createIntArray
int main
C#
The following C# fragment declares a variable-length array of integers. Before C# version 7.2, a pointer to the array is required, requiring an "unsafe" context. The "unsafe" keyword requires an assembly containing this code to be marked as unsafe.unsafe void DeclareStackBasedArrayUnsafe
C# version 7.2 and later allow the array to be allocated without the "unsafe" keyword, through the use of the
System.Span feature.using System;
void DeclareStackBasedArraySafe
COBOL
The following COBOL fragment declares a variable-length array of recordsDEPT-PERSON having a length specified by the value of PEOPLE-CNT:DATA DIVISION.
WORKING-STORAGE SECTION.
01 DEPT-PEOPLE.
05 PEOPLE-CNT PIC S9 BINARY.
05 DEPT-PERSON OCCURS 0 TO 20 TIMES DEPENDING ON PEOPLE-CNT.
10 PERSON-NAME PIC X.
10 PERSON-WAGE PIC S9V99 PACKED-DECIMAL.
The COBOL VLA, unlike that of other languages mentioned here, is safe because COBOL requires specifying maximum array size. In this example,
DEPT-PERSON cannot have more than 20 items, regardless of the value of PEOPLE-CNT.Java
fixes the size of arrays once they are created, but their size can be determined at runtime.public class Example
Object Pascal
dynamic arrays are allocated on the heap.In this language, it is called a dynamic array. The declaration of such a variable is similar to the declaration of a static array, but without specifying its size. The size of the array is given at the time of its use.
program CreateDynamicArrayOfNumbers;
var
NumberArray: array of LongWord;
begin
SetLength;
NumberArray := 2020;
end.
Removing the contents of a dynamic array is done by assigning it a size of zero.
...
SetLength;
...