C/C++ 가변 길이 배열(Variable-length Array): C언어 표준이었던 것

· by 박승재

일반적으로 C와 C++에서는 배열의 크기를 컴파일 시간에 결정한다. 따라서 배열의 크기는 일반 변수로 정할 수 없으며 컴파일 타임 상수가 되어야 한다.

그런데 C99 표준에 이런 상식을 깨는 문법이 들어왔다.

#include <stdio.h>

int main() {
    int size;
    scanf("%d", &size);
    int array[size]; // ok
    array[0] = 1;
    array[size - 1] = 1;
    printf("size: %d", size);
    return 0;
}

size는 사용자에게 입력을 받는 변수로 컴파일 타입에 정확한 값을 알 수 없다. 하지만 배열은 문제없이 할당된다.

C99에서는 이 문법을 가변 길이 배열(VLA; Variable-length Array)라 부른다.

정의

쉽게 말하자면, 가변 길이 배열(VLA)은 런타임 시간에 배열의 크기를 알아내 할당하는 문법이다.

newmalloc을 사용하는 동적 할당에 비해 코드가 간결해지고, 명시적으로 사용한 메모리를 회수하지 않아도 된다는 장점이 있다.

아래 코드에서 배열은 goto가 실행될 때마다 크기를 바꾸며 재할당된다.

#include <stdio.h>

int main() {
    int n = 1;
LABEL:
    printf("Define array\n");
    int array[n];
    printf("The array has %zu elements\n", sizeof(array) / sizeof(array[0]));
    if (n++ < 10)
        goto LABEL;
    return 0;
}
Define array
The array has 1 elements
Define array
The array has 2 elements
Define array
The array has 3 elements
Define array
The array has 4 elements
Define array
The array has 5 elements
Define array
The array has 6 elements
Define array
The array has 7 elements
Define array
The array has 8 elements
Define array
The array has 9 elements
Define array
The array has 10 elements

참고: Variable-length Array

C99 이후

가변 길이 배열(VLA)은 C99에 표준으로 추가되었지만, C11에서 선택 구현사항으로 변경되었다. 즉, C11 컴파일러는 가변 길이 배열(VLA)을 지원하지 않을 수도 있다.

예를 들어, GCCClang에서는 VLA를 지원하지만 MSVC에서는 VLA를 지원하지 않는다.

만약 컴파일러가 VLA를 지원하는지 확인하려면, __STDC_NO_VLA__ 매크로를 이용하면 된다.

C++에서도 마찬가지로 C++17에서 C11이 부분집합으로 들어왔기 때문에 컴파일러에 따라 지원 여부가 다르다.

참고: C++17 should refer to C11 instead of C99