Variable-length array: Difference between revisions
change |
change |
||
| Line 2: | Line 2: | ||
In [[Computer programming|computer programming]], a '''variable-length array''' ('''VLA'''), also called '''variable-sized''' or '''runtime-sized''', is an [[Array data structure|array data structure]] whose length is determined at [[Execution (computing)#Runtime|runtime]], instead of at [[Compile time|compile time]].<ref name=cray>{{cite web |url=http://docs.cray.com/books/004-2179-001/html-004-2179-001/z893434830malz.html |title=Variable Length Arrays |url-status=dead |archive-url=https://web.archive.org/web/20180126153326/http://docs.cray.com/books/004-2179-001/html-004-2179-001/z893434830malz.html |archive-date=2018-01-26}}</ref> In the language [[C (programming language)|C]], the VLA is said to have a variably modified [[Data type|data type]] that depends on a value (see [[Dependent type]]). | In [[Computer programming|computer programming]], a '''variable-length array''' ('''VLA'''), also called '''variable-sized''' or '''runtime-sized''', is an [[Array data structure|array data structure]] whose length is determined at [[Execution (computing)#Runtime|runtime]], instead of at [[Compile time|compile time]].<ref name=cray>{{cite web |url=http://docs.cray.com/books/004-2179-001/html-004-2179-001/z893434830malz.html |title=Variable Length Arrays |url-status=dead |archive-url=https://web.archive.org/web/20180126153326/http://docs.cray.com/books/004-2179-001/html-004-2179-001/z893434830malz.html |archive-date=2018-01-26}}</ref> In the language [[C (programming language)|C]], the VLA is said to have a variably modified [[Data type|data type]] that depends on a value (see [[Dependent type]]). | ||
The main purpose of VLAs is to simplify programming of [[Numerical method|numerical algorithms]]. | The main purpose of VLAs is to simplify programming of [[Numerical method|numerical algorithms]].{{citation-needed|date=December 2025}} | ||
Programming languages that support VLAs include [[Ada (programming language)|Ada]], [[ALGOL 68]] (for non-flexible rows), [[APL (programming language)|APL]], [[C Sharp (programming language)|C#]] (as unsafe-mode [[Stack-based memory allocation|stack-allocated]] arrays), [[COBOL]], [[Fortran]] 90, [[J (programming language)|J]], and [[Object Pascal]] (the language used in [[Software:Delphi|Delphi]] and [[Software:Lazarus|Lazarus]], that uses FPC). [[C99]] introduced support for VLAs, although they were subsequently relegated in [[C11 (C standard revision)|C11]] to a conditional feature, which implementations are not required to support;<ref>{{cite web |url=https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html |title=Variable Length – Using the GNU Compiler Collection (GCC) |publisher=}}</ref><ref>ISO 9899:2011 Programming Languages – C 6.7.6.2 4.</ref> on some platforms, VLAs could be implemented formerly with <code>alloca()</code> or similar functions. | Programming languages that support VLAs include [[Ada (programming language)|Ada]], [[ALGOL 68]] (for non-flexible rows), [[APL (programming language)|APL]], [[C Sharp (programming language)|C#]] (as unsafe-mode [[Stack-based memory allocation|stack-allocated]] arrays), [[COBOL]], [[Fortran]] 90, [[J (programming language)|J]], and [[Object Pascal]] (the language used in [[Software:Delphi|Delphi]] and [[Software:Lazarus|Lazarus]], that uses FPC). [[C99]] introduced support for VLAs, although they were subsequently relegated in [[C11 (C standard revision)|C11]] to a conditional feature, which implementations are not required to support;<ref>{{cite web |url=https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html |title=Variable Length – Using the GNU Compiler Collection (GCC) |publisher=}}</ref><ref>ISO 9899:2011 Programming Languages – C 6.7.6.2 4.</ref> on some platforms, VLAs could be implemented formerly with <code>alloca()</code> or similar functions. | ||
Growable arrays (also called [[Dynamic array|dynamic array]]s) 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 ([[JavaScript]], [[Java (programming language)|Java]], [[Python (programming language)|Python]], [[R (programming language)|R]], etc.) only support growable arrays. Even in languages that support variable-length arrays, it's often recommended to avoid using (stack-based) variable-length arrays, and instead use ([[ | Growable arrays (also called [[Dynamic array|dynamic array]]s) 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 ([[JavaScript]], [[Java (programming language)|Java]], [[Python (programming language)|Python]], [[R (programming language)|R]], etc.) only support growable arrays. Even in languages that support variable-length arrays, it's often recommended to avoid using (stack-based) variable-length arrays, and instead use ([[C dynamic memory allocation|heap-based]]) dynamic arrays.<ref>{{cite web |last=Raymond |first=Eric S. |date=2000 |url=https://tldp.org/HOWTO/Software-Release-Practice-HOWTO/develpractice.html |title=Raymond Software Release Practice Howto: 6. Good development practice |website=The Linux Documentation Project}}</ref> | ||
==Memory== | ==Memory== | ||
| Line 64: | Line 64: | ||
=== C === | === C === | ||
[[C (programming language)|C]] | Certain [[C (programming language)|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 <code>readAndProcess()</code> returns. | 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 <code>readAndProcess()</code> returns. | ||
| Line 93: | Line 93: | ||
float readAndProcess(int n) { | float readAndProcess(int n) { | ||
float (*vals)[n] = | float (*vals)[n] = malloc(sizeof(float[n])); | ||
for (int i = 0; i < n; ++i) { | for (int i = 0; i < n; ++i) { | ||
| Line 106: | Line 106: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== C++ === | === C++ === | ||
| Line 149: | Line 147: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== | ===COBOL=== | ||
The following [[COBOL]] fragment declares a variable-length array of records <code>DEPT-PERSON</code> having a length (number of members) specified by the value of <code>PEOPLE-CNT</code>: | The following [[COBOL]] fragment declares a variable-length array of records <code>DEPT-PERSON</code> having a length (number of members) specified by the value of <code>PEOPLE-CNT</code>: | ||
<syntaxhighlight lang="cobolfree"> | <syntaxhighlight lang="cobolfree"> | ||
| Line 160: | Line 158: | ||
10 PERSON-WAGE PIC S9(7)V99 PACKED-DECIMAL. | 10 PERSON-WAGE PIC S9(7)V99 PACKED-DECIMAL. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
The [[COBOL]] VLA, unlike that of other languages mentioned here, is safe because COBOL requires specifying maximum array size. In this example, <code>DEPT-PERSON</code> cannot have more than 20 items, regardless of the value of <code>PEOPLE-CNT</code>. | |||
=== Java === | === Java === | ||
Latest revision as of 20:30, 14 April 2026
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 runtime, instead of at compile time.[1] In the language C, the VLA is said to have a variably modified data type that depends on a value (see Dependent type).
The main purpose of VLAs is to simplify programming of numerical algorithms.[citation needed]
Programming languages that support VLAs include Ada, ALGOL 68 (for non-flexible rows), APL, C# (as unsafe-mode stack-allocated arrays), COBOL, Fortran 90, J, and Object Pascal (the language used in Delphi and Lazarus, that uses FPC). C99 introduced support for VLAs, although they were subsequently relegated in C11 to a conditional feature, which implementations are not required to support;[2][3] on some platforms, VLAs could be implemented formerly with alloca() or similar functions.
Growable arrays (also called dynamic 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 (JavaScript, Java, Python, R, etc.) only support growable arrays. Even in languages that support variable-length arrays, it's often recommended to avoid using (stack-based) variable-length arrays, and instead use (heap-based) dynamic arrays.[4]
Memory
Allocation
- The GNU Compiler Collection (GCC) for C allocates memory for VLAs with automatic storage duration on the stack.[5] 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 (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
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
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(int n) {
float vals[n];
for (int i = 0; i < n; ++i) {
scanf("%f", &vals[i]);
}
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.[6] The C23 standard makes VLA types mandatory again. Only creation of VLA objects with automatic storage duration is optional.[7] 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.[8] With the Linux 4.20 kernel, the Linux kernel is effectively VLA-free.[9]
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.[10] 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 <stdio.h>
#include <stdlib.h>
float readAndProcess(int n) {
float (*vals)[n] = malloc(sizeof(float[n]));
for (int i = 0; i < n; ++i) {
scanf("%f", &(*vals)[i]);
}
float ret = process(n, *vals);
free(vals);
return ret;
}
C++
While C++ does not support stack-allocated variable length arrays (unlike C which does), 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 as std::vector is probably better. This is because the existing collection types in C++ automatically use "resource acquisition is initialization" (RAII), and will automatically de-allocate once going out of scope.
int* createIntArray(size_t n) {
return new int[n];
}
int main(int argc, char* argv[]) {
int* a = createIntArray(5);
// do something with the array
delete[] a;
}
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(int size)
{
int* p = stackalloc int[size];
p[0] = 123;
}
C# version 7.2 and later allow the array to be allocated without the "unsafe" keyword, through the use of the System.Span<T> feature.[11]
using System;
void DeclareStackBasedArraySafe(int size)
{
Span<int> a = stackalloc int[size];
a[0] = 123;
}
COBOL
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 specifying maximum array size. In this example, DEPT-PERSON cannot have more than 20 items, regardless of the value of PEOPLE-CNT.
Java
Java fixes the size of arrays once they are created, but their size can be determined at runtime.
public class Example {
public static int[] createIntArray(int size) {
return new int[size];
}
public static void main(String[] args) {
try {
String s = IO.readln("Input an integer for an array size: ");
int size = Integer.parseInt(s);
int[] a = createArray(size);
System.out.printf("int[] of size %d created", size);
} catch (NumberFormatException e) {
System.err.printf("Invalid integer read: %s%n", e.getMessage());
}
}
}
Object Pascal
Object Pascal dynamic arrays are allocated on the heap.[12]
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
- ↑ 1.0 1.1 "Variable Length Arrays". http://docs.cray.com/books/004-2179-001/html-004-2179-001/z893434830malz.html.
- ↑ "Variable Length – Using the GNU Compiler Collection (GCC)". https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html.
- ↑ ISO 9899:2011 Programming Languages – C 6.7.6.2 4.
- ↑ Raymond, Eric S. (2000). "Raymond Software Release Practice Howto: 6. Good development practice". https://tldp.org/HOWTO/Software-Release-Practice-HOWTO/develpractice.html.
- ↑ "Code Gen Options - The GNU Fortran Compiler". https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html.
- ↑ § 6.10.8.3 of the C11 standard (n1570.pdf)
- ↑ § 6.10.9.3 of the C23 standard (n3054.pdf)
- ↑ Torvalds, Linus (7 March 2018). "LKML: Linus Torvalds: Re: VLA removal (was Re: [RFC 2/2] lustre: use VLA_SAFE)". Linux kernel (Mailing list).
- ↑ "The Linux Kernel Is Now VLA-Free: A Win For Security, Less Overhead & Better For Clang - Phoronix" (in en). https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kills-The-VLA.
- ↑ §6.5.3.4 and §7.20.3 of the C11 standard (n1570.pdf)
- ↑ "stackalloc operator (C# reference)". Microsoft. 10 July 2024. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc.
- ↑ Michaël Van Canneyt. "Free Pascal Reference guide: Dynamic arrays".
