Skip to main content
A Variable-Length Array (VLA) in C is an array data structure whose length is determined at runtime rather than at compile time. Introduced in the C99 standard, VLAs allow the dimension of an array to be specified using a non-constant integer expression. The term “variable” refers exclusively to the evaluation of the size at runtime; once a VLA is instantiated, its size remains fixed for its entire lifetime.

Syntax and Declaration

A VLA is declared similarly to a standard array, but the size specifier is a variable or an expression evaluated during execution.

Technical Constraints and Rules

Working with VLAs introduces specific compiler rules and memory behaviors that differ from standard fixed-size arrays: 1. Struct and Union Membership VLAs cannot be members of a struct or union. This is a strict language constraint. Developers frequently confuse VLAs with Flexible Array Members (FAMs), but FAMs are structurally different (they must be the last member of a struct and have an incomplete type [], relying on heap allocation).
2. Memory Allocation and Safety Unlike dynamic memory allocation via malloc, VLA allocation failure cannot be detected. Because VLAs are typically allocated on the stack frame, evaluating a size expression that exceeds available stack memory results in an uncatchable stack overflow and undefined behavior. There is no mechanism to return a NULL pointer if the allocation fails. 3. Control Flow and Scope Jumping It is illegal to jump into the scope of a VLA from outside of its scope using goto or switch statements. Doing so bypasses the runtime evaluation and allocation of the array, leaving the VLA in an unallocated or invalid state.
4. Size Evaluation and Undefined Behavior The expression defining the size of a VLA must evaluate to an integer value strictly greater than zero. If the size expression evaluates to zero or a negative number, the program exhibits Undefined Behavior. 5. Storage Duration VLAs must have automatic storage duration. They cannot be declared at file scope (globally) and cannot use the static or extern storage class specifiers.
6. Initialization Unlike fixed-size arrays, VLAs cannot be initialized using an initializer list at the point of declaration. They contain indeterminate (garbage) values until explicitly assigned.
7. The sizeof Operator and Side Effects For standard arrays, sizeof is evaluated at compile time, and its operand is never executed. For VLAs, the sizeof operator is evaluated at runtime. The runtime environment calculates the total bytes based on the evaluated length expression multiplied by the size of the data type. Crucially, because the operand of sizeof is evaluated at runtime when applied to a VLA, any side effects within the sizeof operand will execute.
8. Multidimensional VLAs VLAs support multiple dimensions. Any or all of the dimensions can be variable. The compiler handles the underlying pointer arithmetic for row-major memory access dynamically.

Function Prototypes and VLA Parameters

When passing multidimensional VLAs to functions, the variable dimensions must be declared in the parameter list before they are used in the array declarator.
In function prototypes (declarations without definitions), the size expression can be omitted and replaced with an asterisk * to denote a VLA type without specifying the exact variable name.

Standardization Note

While introduced as a mandatory feature in C99, VLAs were made an optional feature in the C11 standard to accommodate implementations where stack memory is highly constrained (e.g., embedded systems). Compilers indicate the lack of VLA support by defining the __STDC_NO_VLA__ macro.
Tired of Poor C Skills? Fix That With Deep Grasping!Learn More