An earlier version of my Pitfalls of VLA in C article
contained an example of usefulness of VLA. But since there are actually
two of them (and I'd be overjoyed being presented with more), they deserve
a dedicated, if low effort, post of their own. After all, those use-cases
are the reason why I opt for -Wvla-larger-than=0 rather than stricter
and more reliable -Wvla.
Size check when passing to function
"Only" a bit over two decades after the standardization of VLA in C language, GCC started giving warnings about passing to functions bigger than declared size of arrays when we actually decide to utilize VLA syntax in parameters.
#include <stdio.h>
void f(const size_t size, const int buf[static size]);
int main(void)
{
int arr[50] = { 0 };
f(10, arr); // acceptable
f(50, arr); // correct
f(100, arr); // *WARNING*
return 0;
}
Added bonus: explicit size annotation
Multidimensional arrays
Dynamically allocating multi-dimensional arrays where the inner dimensions are not known until runtime is really simplified using VM types. It isn't even as unsafe as aVLA since there's no arbitrary stack allocation.
int (*arr)[n][m] = malloc(sizeof *arr); // `n` and `m` are variables with dimensions
if (arr) {
// (*arr)[i][j] = ...;
free(arr);
}
The VLA-free alternatives aren't as attractive:
- piecemeal allocation
int **arr = malloc(n * (sizeof *arr)); if (arr) { for (int i = 0; i < n; ++i) { arr[i] = malloc(m * (sizeof *arr[i])); } // arr[i][j] = ... for (int i = 0; i < n; ++i) { free(arr[i]); } free(arr); } - 1D array with offsets
int *arr = malloc(n * m * (sizeof *arr)); if (arr) { // arr[i*n + j] = ... free(arr); } - big fixed array
int arr[SAFE_SIZE][SAFE_SIZE]; // SAFE_SIZE must be safe for SAFE_SIZE*SAFE_SIZE // arr[i][j] = ...;