Variable-length array
In computer programming, a variable-length array (VLA), also called variable-sized or runtime-sized, is an array data structure whose length is determined at run time (instead of at compile time).[1] In C, the VLA is said to have a variably modified type that depends on a value (see Dependent type).
The main purpose of VLAs is to simplify programming of numerical algorithms.
Programming languages that support VLAs include Ada, Algol 68 (for non-flexible rows), APL, C99 (although subsequently relegated in C11 to a conditional feature, which implementations are not required to support;[2][3] on some platforms, could be implemented previously with alloca() or similar functions) and C# (as unsafe-mode stack-allocated arrays), COBOL, Fortran 90, J, and Object Pascal (the language used in Borland Delphi and Lazarus, that uses FPC).
Memory[edit]
Allocation[edit]
- The GNU C Compiler allocates memory for VLAs with automatic storage duration on the stack.[4] 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[edit]
C99[edit]
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 read_and_process() returns.
float read_and_process(int n)
{
float vals[n];
for (int i = 0; i < n; ++i)
vals[i] = read_val();
return process(n, vals);
}
In C99, the length parameter must come before the variable-length array parameter in function calls.[1] In C11, a __STDC_NO_VLA__ macro is defined if VLA is not supported.[5] 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. [6] With the Linux 4.20 kernel, Linux kernel is effectively VLA-free.[7]
Although C11 does not explicitly name a size-limit for VLAs, some readings believe it should have the same maximum size as all other objects, i.e. SIZE_MAX bytes.[8] However, this reading 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-like syntax with dynamic storage with a help of a pointer to an array.
float read_and_process(int n)
{
float (*vals)[n] = malloc(sizeof(float[n]));
for (int i = 0; i < n; ++i)
(*vals)[i] = read_val();
float ret = process(n, *vals);
free(vals);
return ret;
}
Ada[edit]
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 (Positive range <>) of Float;
function Read_And_Process (N : Integer) return Float is
Vals : Vals_Type (1 .. N);
begin
for I in 1 .. N loop
Vals (I) := Read_Val;
end loop;
return Process (Vals);
end Read_And_Process;
Fortran 90[edit]
The equivalent Fortran 90 function is
function read_and_process(n) result(o)
integer,intent(in)::n
real::o
real,dimension(n)::vals
integer::i
do i = 1,n
vals(i) = read_val()
end do
o = process(vals)
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 (external) functions must first be declared, and the array length must be explicitly passed as an argument (as in C):
function read_and_process(n) result(o)
integer,intent(in)::n
real::o
real,dimension(n)::vals
real::read_val, process
integer::i
do i = 1,n
vals(i) = read_val()
end do
o = process(vals,n)
end function read_and_process
Cobol[edit]
The following COBOL fragment declares a variable-length array of records DEPT-PERSON having a length (number of members) specified by the value of PEOPLE-CNT:
DATA DIVISION.
WORKING-STORAGE SECTION.
01 DEPT-PEOPLE.
05 PEOPLE-CNT PIC S9(4) BINARY.
05 DEPT-PERSON OCCURS 0 TO 20 TIMES DEPENDING ON PEOPLE-CNT.
10 PERSON-NAME PIC X(20).
10 PERSON-WAGE PIC S9(7)V99 PACKED-DECIMAL.
The COBOL VLA, unlike that of other languages mentioned here, is safe because COBOL requires one to specify the maximal array size – in this example, DEPT-PERSON cannot have more than 20 items, regardless of the value of PEOPLE-CNT.
C#[edit]
The following C# fragment declares a variable-length array of integers. Prior to 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(int size)
{
int *pArray = stackalloc int[size];
pArray[0] = 123;
}
C# version 7.2 and later allow the array to be allocated without the "unsafe" keyword, through the use of the Span feature.[9]
void DeclareStackBasedArraySafe(int size)
{
Span<int> stackArray = stackalloc int[size];
stackArray[0] = 123;
}
Object Pascal[edit]
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(Size: Integer);
var
NumberArray: array of LongWord;
begin
SetLength(NumberArray, Size);
NumberArray[0] := 2020;
end.
Removing the contents of a dynamic array is done by assigning it a size of zero.
...
SetLength(NumberArray, 0);
...
References[edit]
- ^ a b "Variable Length Arrays". Archived from the original on 2018-01-26.
- ^ "Variable Length – Using the GNU Compiler Collection (GCC)".
- ^ ISO 9899:2011 Programming Languages – C 6.7.6.2 4.
- ^ "Code Gen Options - The GNU Fortran Compiler".
- ^ § 6.10.8.3 of the C11 standard (n1570.pdf)
- ^ "LKML: Linus Torvalds: Re: VLA removal (was Re: [RFC 2/2] lustre: use VLA_SAFE)". lkml.org.
- ^ "The Linux Kernel Is Now VLA-Free: A Win For Security, Less Overhead & Better For Clang - Phoronix". www.phoronix.com.
- ^ §6.5.3.4 and §7.20.3 of the C11 standard (n1570.pdf)
- ^ "stackalloc operator (C# reference)". Microsoft.