Incomputer programming, avariable-length array (VLA), also calledvariable-sized orruntime-sized, is anarray data structure whose length is determined atruntime, instead of atcompile time.[1] In the languageC, the VLA is said to have a variably modifieddata type that depends on a value (seeDependent type).
The main purpose of VLAs is to simplify programming ofnumerical algorithms.
Programming languages that support VLAs includeAda,ALGOL 68 (for non-flexible rows),APL,C# (as unsafe-modestack-allocated arrays),COBOL,Fortran 90,J, andObject Pascal (the language used inDelphi andLazarus, that uses FPC).C99 introduced support for VLAs, although they were subsequently relegated inC11 to a conditional feature, which implementations are not required to support;[2][3] on some platforms, VLAs could be implemented formerly withalloca() or similar functions.
Growable arrays (also calleddynamic 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]
The following is the same example inAda. Ada arrays carry their bounds with them, so there is no need to pass the length to the Process function.
typeVals_Typeisarray(Positiverange<>)ofFloat;functionRead_And_Process(N:Integer)returnFloatisVals:Vals_Type(1..N);beginforIin1..NloopVals(I):=Read_Val;endloop;returnProcess(Vals);endRead_And_Process;
The equivalentFortran 90 function is
functionread_and_process(n)result(o)integer,intent(in)::nreal::oreal,dimension(n)::valsinteger::idoi=1,nvals(i)=read_val()end doo=process(vals)end functionread_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):
functionread_and_process(n)result(o)integer,intent(in)::nreal::oreal,dimension(n)::valsreal::read_val,processinteger::idoi=1,nvals(i)=read_val()end doo=process(vals,n)end functionread_and_process
C supports variable-length arrays. Variable-length arrays are not supported inC++.
The followingC99 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 whenreadAndProcess() returns.
floatreadAndProcess(intn){floatvals[n];for(inti=0;i<n;++i){scanf("%f",&vals[i]);}returnprocess(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, theLinux 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 thanSIZE_MAX.
It is possible to have VLA object with dynamic storage by using a pointer to an array.
#include<stdio.h>#include<stdlib.h>floatreadAndProcess(intn){float(*vals)[n]=malloc(sizeof(float[n]));for(inti=0;i<n;++i){scanf("%f",&(*vals)[i]);}floatret=process(n,*vals);free(vals);returnret;}
WhileC++ does not support stack-allocated variable length arrays (unlike C which does), they may be allowed by some compiler extensions such as onGCC andClang. 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" (RAII), and will automatically de-allocate once going out of scope.
int*createIntArray(size_tn){returnnewint[n];}intmain(intargc,char*argv[]){int*a=createIntArray(5);// do something with the arraydelete[]a;}
The followingC# 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.
unsafevoidDeclareStackBasedArrayUnsafe(intsize){int*p=stackallocint[size];p[0]=123;}
C# version 7.2 and later allow the array to be allocated without the "unsafe" keyword, through the use of theSystem.Span<T> feature.[11]
usingSystem;voidDeclareStackBasedArraySafe(intsize){Span<int>a=stackallocint[size];a[0]=123;}
The followingCOBOL fragment declares a variable-length array of recordsDEPT-PERSON having a length (number of members) specified by the value ofPEOPLE-CNT:
DATADIVISION.WORKING-STORAGESECTION.01DEPT-PEOPLE.05PEOPLE-CNTPIC S9(4)BINARY.05DEPT-PERSONOCCURS0TO20TIMESDEPENDINGONPEOPLE-CNT.10PERSON-NAMEPIC X(20).10PERSON-WAGEPIC S9(7)V99PACKED-DECIMAL.
TheCOBOL 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 ofPEOPLE-CNT.
Java fixes the size of arrays once they are created, but their size can be determined at runtime.
publicclassExample{publicstaticint[]createIntArray(intsize){returnnewint[size];}publicstaticvoidmain(String[]args){try{Strings=IO.readln("Input an integer for an array size: ");intsize=Integer.parseInt(s);int[]a=createArray(size);System.out.printf("int[] of size %d created",size);}catch(NumberFormatExceptione){System.err.printf("Invalid integer read: %s%n",e.getMessage());}}}
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.
programCreateDynamicArrayOfNumbers(Size:Integer);varNumberArray:arrayofLongWord;beginSetLength(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);...