Fact-checked by Grok 2 weeks ago

Variable-length array

A variable-length array (VLA), also known as a runtime-sized or variable-sized array, is an array data structure in programming whose length is not fixed at compile time but is instead determined by an expression evaluated at runtime. This feature allows for flexible allocation of array space on the stack without the need for explicit dynamic memory management functions like malloc and free. VLAs were formally introduced in the ISO standard as a new array type to address the limitations of fixed-size arrays in prior versions like and , enabling more portable and efficient handling of dynamically sized data in applications such as numerical computing and matrix operations. In , they are declared using syntax such as int n = 10; int arr[n];, where the size n is a non-constant expression, and the array receives automatic storage duration, meaning it is allocated upon declaration and deallocated when the enclosing block or function scope ends. VLAs were made optional in the and standards due to implementation complexities, potential for stack overflows from large runtime sizes, and challenges with features like goto statements that could bypass proper deallocation. In the C23 standard (ISO/IEC 9899:2024), support for variably modified types (including VLA types) is mandatory, although automatic storage duration VLAs remain optional. Despite their optional status for automatic storage in recent standards, VLAs remain supported as an extension in compilers like , which allows them in C90 mode and even in C++ for enhanced compatibility with legacy code. Key advantages include simplified code for variable-sized buffers and multidimensional passed as function parameters, such as void func(int n, int matrix[n][n]);, but limitations persist: VLAs cannot have static or external linkage, cannot be members of structures or unions, and their size must evaluate to a positive to avoid . Similar concepts appear in other languages, such as Fortran's allocatable or Ada's unconstrained types, but the term "VLA" is most closely associated with .

Overview

Definition

A variable-length array (VLA), also known as a runtime-sized or variable-sized array, is an array data structure whose length is determined at runtime rather than at compile-time. This allows the array's dimensions to be specified using expressions evaluated during program execution, providing flexibility for scenarios where the required size cannot be predetermined statically. In contrast, fixed-size arrays require dimensions defined by constant expressions that are resolved at compile time, limiting their adaptability to known quantities. VLAs maintain the contiguous memory layout typical of static arrays, ensuring elements are stored sequentially for efficient access and traversal. They belong to a broader category of variably modified types, where the size depends on values, but unlike dynamically resizable structures, VLAs have a fixed length once declared. This design supports direct indexing and compatibility with operations without additional . Common use cases for VLAs include temporary buffers in functions for processing variable amounts of , such as reading input of length, or matrices in numerical computations where dimensions, like the order of a , are computed at . These applications benefit from the ability to declare arrays locally without explicit dynamic allocation, simplifying code for tasks in scientific computing and .

History

The concept of flexible or variable-length arrays originated in the with languages designed for scientific and . In , introduced in 1964, based variables allowed for dynamic allocation of storage, including arrays whose sizes could be determined at , providing flexibility for list processing and variable-sized data structures. Similarly, , finalized in 1968, introduced flexible arrays as a core feature, enabling dynamic resizing of array variables to support evolving data needs, such as extending strings or other collections without fixed bounds at . Extensions for variable-length structures appeared in other languages during this period. , through its 1968 standard, incorporated the OCCURS DEPENDING ON clause, allowing tables (arrays) to have lengths determined at based on a controlling item, which facilitated handling of variable record sizes in business . Ada, standardized in 1983, supported unconstrained array types where bounds could be specified at , promoting safe and modular handling of dynamic in and real-time systems. The 1990s saw further standardization in numerical computing languages. Fortran 90, released in 1991, introduced allocatable arrays, permitting deferred-shape arrays whose sizes and bounds are allocated dynamically via the ALLOCATE statement, addressing limitations of fixed-size arrays in scientific simulations. In C, variable-length arrays (VLAs) were formally added in the standard (ISO/IEC 9899:1999), primarily to simplify implementations of numerical algorithms by allowing runtime-sized automatic arrays and providing a portable alternative to the non-standard alloca function for allocation. Subsequent developments reflected mixed adoption and refinements. The C11 standard (ISO/IEC 9899:2011) made VLA support optional, acknowledging implementation challenges such as stack overflow risks and complexity in embedded environments, though creation of VLA objects with automatic storage duration remains the key optional aspect. Some compilers, including , provide the -Wvla warning option for VLAs due to portability and security concerns like potential unbounded stack usage; this option has been available since GCC 4.0, though full has not occurred as of 2025. VLAs were never standardized in C++, where dynamic arrays are handled via std::vector from the C++98 standard onward for better safety and abstraction. The C23 standard (ISO/IEC 9899:2023) mandates support for variably modified types, including VLAs in function parameters, while keeping VLAs with automatic storage duration optional.

Key Characteristics

Memory Allocation

Variable-length arrays (VLAs) are primarily allocated on the call , where they are integrated into the 's activation record alongside other local variables. This placement ensures that the array's is managed automatically by the environment as part of the stack frame. The allocation process begins with the computation of the array's size at , often derived from function parameters or other dynamic values. Upon function entry, the required space is reserved on the by adjusting the stack pointer, without the need for explicit allocation calls. In contrast to heap allocation methods like malloc in C, VLAs require no manual deallocation and avoid the overhead of separate routines, though they are constrained by the stack's fixed size limit, typically 8 MB on many systems. For multidimensional VLAs, storage is provided contiguously in memory, with dimensions determined at runtime; for example, in C, a declaration such as int arr[n][m] where n and m are variables results in a block of memory sized according to the product of the dimensions and the element type. However, exceeding the available stack space can lead to stack overflow, potentially causing program termination or undefined behavior. Their lifetime is tied to the enclosing scope, with automatic deallocation upon exit.

Lifetime Management

Variable-length arrays (VLAs) are automatically allocated upon entry to the or in which they are declared, with their duration tied to the automatic class. This allocation occurs as part of the standard frame setup, where the size of the VLA, determined at , is added to the pointer adjustment at the point of declaration. Deallocation happens automatically upon exit from that , typically through unwinding during return or termination, ensuring the memory is reclaimed without explicit intervention. The scope of a is strictly local to the or where it is declared, meaning it cannot be accessed outside that . Attempting to return a pointer to a VLA from its declaring results in a , as the array's memory is deallocated upon exit, leading to if dereferenced afterward. This temporary nature enforces disciplined use, preventing accidental persistence of stack-allocated resources beyond their intended lifetime. VLAs impose specific restrictions to maintain their runtime viability: the array size must be computable from values known prior to the declaration statement, ensuring the expression evaluates to a positive without forward references. In C, VLAs cannot serve as members of structures or unions, nor can they be used in initializers for other objects, as their variably modified types complicate compile-time analysis. Additionally, VLAs are confined to block scope or scope and lack external or static linkage. In recursive functions, each invocation allocates its own independent on the , which can accumulate and lead to stack exhaustion if the recursion depth is sufficient to exceed available stack space. This behavior mirrors the stack-based nature of automatic variables, where nested calls compound memory demands without bound. Unlike heap-allocated arrays, which require manual allocation via functions like malloc and explicit deallocation with free to manage persistence across scopes, VLAs eliminate the need for such operations, thereby mitigating risks of memory leaks from forgotten frees. However, this convenience comes at the cost of limited lifetime, as heap allocations can survive function boundaries and be returned safely, whereas VLAs cannot.

Advantages and Disadvantages

Advantages

Variable-length arrays (VLAs) provide significant benefits in scenarios requiring runtime-determined sizes, particularly in performance-critical and numerical applications. Their stack-based allocation enables faster allocation and deallocation than traditional heap-based dynamic memory, as it avoids the overhead of function calls such as malloc and free, simply adjusting the stack pointer upon declaration and automatically reclaiming space upon scope exit. This efficiency stems from the language standard's design to handle such arrays "in a convenient and efficient way" without manual intervention. Furthermore, VLAs benefit from improved cache locality due to their contiguous placement on the , near other local variables, which enhances data access speeds by increasing cache hit rates compared to scattered heap allocations. Stack-allocated data inherently exhibits high locality, allowing even small to achieve high hit rates and reduce memory access latencies. In terms of simplicity, VLAs offer automatic lifetime management within local scopes, eliminating for memory handling and minimizing risks associated with manual deallocation errors. This reduces programming complexity, as arrays are deallocated predictably at the end of the block without explicit cleanup. VLAs are especially suitable for numerical code, where they enable the creation of runtime-sized matrices or vectors without relying on pointers or dynamic allocation routines, simplifying algorithms like that operate on variably dimensioned data. For instance, in , a can declare a two-dimensional VLA based on input parameters to perform operations directly on the array, avoiding the indirection of heap-allocated pointers. The feature addresses a key limitation in prior standards, making languages like C more viable for numerical computing by supporting arrays "whose size is known only at execution time." Built-in support in standards such as enhances portability, allowing developers to use VLAs without resorting to compiler-specific extensions or non-standard libraries. This standardization promotes consistent behavior across compliant implementations, facilitating in diverse environments.

Disadvantages

One significant drawback of variable-length arrays (VLAs) is the risk of , as they are allocated on the with automatic storage duration, and large sizes or deep can exhaust available , leading to program crashes. For instance, declaring a VLA of one million integers in C could consume approximately 4 of , which exceeds typical stack limits on many systems (e.g., 1-8 ), resulting in if the allocation fails due to insufficient resources. This issue is particularly acute in or resource-constrained environments where stack sizes are limited. VLAs are inherently non-resizable; their size is determined at upon and remains fixed throughout their lifetime, unlike dynamic containers such as C++'s std::vector that support resizing via reallocation. The size expression is evaluated only once at the point of (C11 §6.7.6.2), preventing any subsequent adjustments without recreating the array, which introduces inefficiency for scenarios requiring flexible growth. Portability concerns arise because VLAs are an optional feature in the standard and remain optional for automatic storage declarations in the C23 standard (ISO/IEC 9899:2024), allowing implementations to omit support by defining the __STDC_NO_VLA__ as 1, although variably modified types are now mandatory. Compilers like issue warnings via the -Wvla flag to highlight potential issues, treating VLAs as extensions in pre-C99 modes, while others, such as Microsoft Visual C++, do not support them at all, rendering code non-compilable across environments. Debugging VLAs presents challenges due to their runtime-determined sizes, which hinder static tools and compilers from performing thorough bounds checking or optimization. If the size evaluates to zero or a negative value, the behavior is undefined per the C standard (C11 §6.7.6.2 and §J.2), potentially causing segmentation faults or erratic program execution without clear diagnostics. This variability complicates error detection, as tools must account for dynamic dimensions rather than fixed ones. Finally, VLAs are not suitable for persistent data, as their automatic storage duration ties their lifetime to the declaring scope, deallocating them upon or exit without the option for explicit persistence. To retain VLA contents beyond this scope, programmers must manually copy the data to heap-allocated using functions like malloc, adding overhead and risk of leaks if not managed properly ( §6.2.4).

Implementations

In C

Variable-length arrays (VLAs) were introduced in the standard as a feature allowing the declaration of arrays with sizes determined at rather than . The basic syntax involves using a runtime-evaluated expression as the array size, such as int arr[n]; where n is a variable or expression of type. This allocation occurs automatically on the when the declaration is reached, and the array is deallocated upon exiting the containing block scope. Multidimensional VLAs are also supported, enabling declarations like int matrix[n][m]; where both n and m can be values. Such arrays are stored contiguously in , similar to fixed-size multidimensional arrays, facilitating efficient access patterns in numerical computations. VLAs come with several restrictions to ensure portability and safety. The size expression must evaluate to a positive value greater than zero at ; a zero or negative size results in . VLAs must have automatic storage duration and cannot be declared at file scope, possess external or static linkage, or serve as members of structures or unions. For function parameters, direct VLA types are not permitted—instead, equivalent pointer types are used, as in void func(int n, int arr[n]); which adjusts to void func(int n, int *arr); in the , treating arr as a pointer to the first . The C11 standard made VLA support optional for implementations, with the preprocessor macro __STDC_NO_VLA__ defined to 1 if VLAs of automatic storage duration are not provided (though variably modified types and dynamically allocated VLAs remain required). Compilers such as enable VLA support by default in C99 and later modes via flags like -std=c99 or -std=gnu99, but stricter conformance modes may require explicit specification. A notable pitfall involves the sizeof operator applied to VLA types: within a function prototype scope, sizeof a VLA parameter yields the size of a pointer to the array's element type rather than the complete array size based on n. Side effects in the size expression, such as function calls, are not evaluated in sizeof contexts. Furthermore, modern compilers often issue warnings about VLA usage due to risks like stack overflows from excessively large runtime sizes; for instance, GCC's -Wvla option (enabled under -pedantic for pre-C99 modes) alerts developers to their presence, and -Wvla-larger-than=bytes can flag allocations exceeding a specified limit.

In Ada

In Ada, support for variable-length arrays has been available since the language's initial standardization in Ada 83, allowing arrays whose bounds are determined at rather than . This is achieved through unconstrained array types, declared without fixed index bounds using the box notation <> to indicate variability. For example, a subtype for the length can be defined as subtype Length is Positive;, followed by a declaration like Arr: array(1..N) of Integer; where N is a variable of type Length. Such arrays are instantiated when the object is created, with bounds specified at that point, enabling flexible sizing based on program needs. Unconstrained arrays provide , where the subtype is but the specific bounds vary per object. A type declaration might look like type [Vector](/page/Vector) is [array](/page/Array)(Positive [range](/page/Range) <>) of Real;, and an object can then be created with bounds, such as within a declare block for stack allocation: declare V: [Vector](/page/Vector)(1..N); where N is computed at execution time. For dynamic allocation on the , types are used in conjunction with the new , allowing pointers to unconstrained arrays, as in type Vector_Access is [access](/page/Access) [Vector](/page/Vector); V_Ptr: Vector_Access := new [Vector](/page/Vector)'(1..N => 0.0);. This approach supports stack-based variable-length arrays via local declare blocks while enabling allocation for longer lifetimes. Ada emphasizes safety in handling variable-length arrays through built-in runtime checks for index validity, ensuring that subscripting operations respect the array's bounds and preventing buffer overflows. These checks are automatically enforced by the compiler-generated code, raising a Constraint_Error if violated. Additionally, arrays integrate seamlessly with Ada's tasking model for concurrency, where protected objects or can safely share array data across tasks without race conditions, leveraging the language's strong typing and synchronization primitives. Unlike fixed arrays, which have compile-time constant bounds (e.g., type Fixed_Table is array(1..10) of Integer;), variable-length arrays in Ada leverage unconstrained types for runtime flexibility. A key distinction arises in record types, where discriminants can parameterize array components to vary their size based on the record's value, as in type Variable_Record (Size: Positive) is record Data: array(1..Size) of [Integer](/page/Integer); end record;. This discriminant mechanism allows compile-time knowledge of variability while deferring actual bounds to instantiation, enhancing over purely fixed structures.

In Fortran

In Fortran 90, variable-length arrays are primarily implemented through allocatable arrays, which allow dynamic memory allocation at runtime using the ALLOCATE statement. An allocatable array is declared with the ALLOCATABLE attribute, specifying deferred shape bounds, such as real, allocatable :: arr(:). The array's size is then set explicitly with allocate(arr(n)), where n is a runtime expression determining the extent. This mechanism supports flexible array dimensions without requiring fixed sizes at compile time, enabling efficient handling of data whose size is unknown until execution. Allocatable arrays are typically allocated on the heap, providing scalability for large datasets and avoiding stack overflow issues common with automatic arrays declared using runtime expressions in procedure scopes. In contrast, automatic arrays reside on the stack and are deallocated upon procedure exit, but they are limited by stack size constraints. Deallocation of allocatable arrays is performed explicitly with the DEALLOCATE statement, such as deallocate(arr), to free memory and prevent leaks; failure to do so can lead to resource exhaustion in long-running programs. Multidimensional allocatable arrays follow the same pattern, with deferred shapes like real, allocatable :: matrix(:,:) allocated as allocate(matrix(m, n)), where m and n are runtime values, facilitating operations on matrices or tensors with variable dimensions. Since 90, local allocatable arrays without the SAVE attribute are automatically deallocated upon leaving the where they are declared. 2003 introduced enhancements such as the SOURCE= specifier in ALLOCATE, allowing initialization from another array, e.g., allocate(b, source=a). Pointer arrays, also available since 90, serve as an alternative for dynamic allocation but require explicit association and disassociation, making them more prone to errors. Allocatable arrays are generally preferred for data ownership in modern code due to their automatic memory management and contiguous storage guarantees, which improve performance in numerical algorithms. In numerical libraries and scientific simulations, allocatable arrays are extensively used to manage structures with variable sizes, such as sparse matrices in linear algebra routines or grids in . For instance, the Fortran Standard Library's sparse module employs allocatable arrays to represent compressed sparse row formats, enabling efficient storage and operations on matrices with predominantly zero elements. Similarly, geotechnical simulation tools like TRIGRS leverage allocatable arrays for dynamic allocation of slope profiles and grid data, accommodating arbitrary problem sizes without recompilation.

In Other Languages

In , variable-length tables are supported through the OCCURS DEPENDING ON clause, which allows the number of occurrences to be determined at based on a specified item. For example, a table can be declared as 01 TABLE OCCURS 1 TO 100 DEPENDING ON N TIMES, where N defines the actual length during execution. In C#, arrays are fixed-size once created, such as int[] arr = new int[n]; where n is evaluated at but cannot be changed afterward. True variable-length array can be achieved using unsafe with pointers or through spans for bounded views, though the language encourages List<T> for dynamically resizable collections. Object Pascal, as implemented in , supports dynamic arrays declared with an open-ended syntax like type TArray = array of Integer;, which are allocated on the and resized at runtime using the SetLength procedure, such as SetLength(arr, n);. Other languages offer varying support for variable-length arrays; provides variable storage through controlled variables for adjustable extents in large aggregates, while uses open arrays in procedure parameters to handle bounds determined by the caller. Java lacks native variable-length arrays, relying on methods like Array.newInstance for dynamic creation or collections like ArrayList as alternatives, and uses lists as inherently dynamic sequences that grow or shrink as needed.

References

  1. [1]
    Array declaration - cppreference.com - C++ Reference
    Jan 31, 2025 · Variable-length arrays. If expression is not an integer constant expression, the declarator is for an array of variable size. Each time the flow ...
  2. [2]
    [PDF] Rationale for International Standard— Programming Languages— C
    C99 adds a new array type called a variable length array type. The ... situations can arise where a variable length array definition is skipped. In ...
  3. [3]
    Variable Length (Using the GNU Compiler Collection (GCC))
    Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++.Missing: definition | Show results with:definition
  4. [4]
    The early history and characteristics of PL/I - ACM Digital Library
    A remem- bered history of PL/I is retrievable by listening to as many people, each of whom was deeply involved in one aspect of its progress.
  5. [5]
    [PDF] ALGOL 68 Session
    The next facility added, in [MR 88], was flexible arrays. These allowed the size of an array variable to be changed dynamically. Ioc flex [I:0] int array;.
  6. [6]
    IBM extensions and COBOL standards
    IBM extensions are features, syntax rules, or behaviors defined by IBM rather than by the COBOL standards.Missing: history | Show results with:history
  7. [7]
    Ada 83 LRM, Sec 3.6: Array Types - Ada Information Clearinghouse
    In particular, for an array of components that are one-dimensional arrays, this means that all components have the same bounds and hence the same length.Missing: runtime | Show results with:runtime
  8. [8]
    Stack Allocation (Using the GNU Compiler Collection (GCC))
    Since C99 Variable Length Arrays offer the same functionality under a portable, more convenient, and safer interface they are recommended instead, in both C99 ...Missing: memory | Show results with:memory
  9. [9]
    NXX20: Variable Length Array (VLA) Allocation Control - ThePhD
    Feb 11, 2025 · Variable Length Arrays (VLAs) are a feature for potentially accessing an implementation-detail of where memory is stored to generate more ...
  10. [10]
    CS360 Lecture notes -- Memory - UTK-EECS
    ... stack and frame pointers. In reality, the stack is a fixed size (typically 8 MB). You could make it grow by using mmap() properly, but that is not what ...
  11. [11]
    Variable length arrays - IBM
    A variable length array, which is a C99 feature, is an array of automatic storage duration whose length is determined at run time.Missing: standard | Show results with:standard
  12. [12]
  13. [13]
    MEM05-C. Avoid large stack allocations - Confluence
    If the array length is derived from an untrusted data source, an attacker can cause the process to perform an excessive allocation on the stack.
  14. [14]
    [PDF] Rationale for International Standard— Programming Languages— C
    UNIX C programs which take advantage of this model are standard conforming ... that variable length arrays are compatible with both an array of known ...
  15. [15]
  16. [16]
    None
    Below is a merged summary of Variable Length Arrays (VLAs) in C11 based on the N1570 standard, consolidating all information from the provided segments. To retain maximum detail and ensure clarity, I will use a table in CSV format for the core information, followed by a narrative summary and a list of useful URLs. The table captures the key aspects (VLAs Optional, Portability, Stack Allocation, Undefined Behavior for Sizes) with all relevant details, references, and notes from the segments.
  17. [17]
  18. [18]
    Variable-length array - PVS-Studio
    Feb 28, 2023 · A variable-length array is an array whose length is determined at runtime. Despite its confusing name, once declared, the length of this array cannot be ...
  19. [19]
    C Dialect Options (Using the GNU Compiler Collection (GCC))
    GCC uses options like `-ansi` and `-std=` to control C dialects, including base standards and GNU dialects, such as `c90`, `gnu90`, `c++98`, and `gnu++98`.
  20. [20]
    [PDF] Reference Manual for the Ada Programming Language ... - DTIC
    Ada is a common language for programming large-scale, real-time systems, designed for DoD and chosen as the new DoD language.
  21. [21]
    Array Types
    ### Summary of Arrays in Ada (Ada Reference Manual, Section 3.6)
  22. [22]
  23. [23]
  24. [24]
    Allocatable Arrays — Fortran Programming Language
    The allocatable attribute provides a safe way for memory handling. In comparison to variables with pointer attribute the memory is managed automatically.
  25. [25]
    Allocatable arrays - IBM
    A deferred-shape array that has the ALLOCATABLE attribute is referred to as an allocatable array. The bounds and shape of the array are determined when you ...
  26. [26]
    [PDF] The New Features of Fortran 2003
    The significant enhancements in the 1991 revision were dynamic storage, structures, derived types, pointers, type parameterization, modules, and array language.
  27. [27]
    ALLOCATE Statement - Intel
    Statement: Dynamically creates storage for allocatable variables and pointer targets.
  28. [28]
    sparse - Fortran-lang/stdlib
    The stdlib_sparse module provides derived types for standard sparse matrix data structures. It also provides math kernels such as sparse matrix-vector product.
  29. [29]
    [PDF] TRIGRS—A Fortran Program for Transient Rainfall Infiltration and ...
    The main program was written in Fortran 90 to take advantage of its ability to allocate arrays dynamically. Consequently the executable can be used to analyze ...
  30. [30]
    Creating variable-length tables (DEPENDING ON) - IBM
    If you do not know before run time how many times a table element occurs, define a variable-length table. To do so, use the OCCURS DEPENDING ON (ODO) clause.
  31. [31]
    Defining a Variable-length Table with the OCCURS DEPENDING ...
    Apr 19, 2022 · In COBOL, you can use the OCCURS DEPENDING ON syntax to define a variable-length table in a data declaration.Missing: extensions | Show results with:extensions
  32. [32]
    The array reference type - C# reference | Microsoft Learn
    The number of dimensions are set when an array variable is declared. The length of each dimension is established when the array instance is created. These ...
  33. [33]
    System.Collections.Generic.List\<T> class - .NET | Microsoft Learn
    Jan 8, 2024 · List<T> is a generic, dynamically sized array, like ArrayList, accessed by zero-based index, and is not guaranteed to be sorted.Missing: fixed | Show results with:fixed
  34. [34]
    Structured Types (Delphi) - RAD Studio - Embarcadero DocWiki
    You can create multidimensional dynamic arrays that are not rectangular. The first step is to call SetLength, passing it parameters for the first n dimensions ...
  35. [35]
    Delphi Intrinsic Routines - RAD Studio - Embarcadero DocWiki
    Sets the length of a string or dynamic-array variable.
  36. [36]
    Controlled storage and attribute - IBM
    Controlled variables are useful when a program requires large data aggregates with adjustable extents.
  37. [37]
    Chapter 6 - Arrays, Types, and Constants - Modula-2
    When the variable named "SizeTwo" is the array sent to the procedure, then "Donkey" will have the limits of 0 and 218. The second procedure definition method is ...
  38. [38]
    Creating New Arrays - The Java™ Tutorials
    In Java, arrays can be created dynamically using `java.lang.reflect.Array.newInstance()`, with syntax `fully_qualified_class_name variable_name[] = { val1, val ...Missing: variable | Show results with:variable
  39. [39]
    Design and History FAQ — Python 3.14.0 documentation
    Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are ...