https://stackoverflow.com/questions/4341570/why-does-a-c-c-compiler-need-know-the-size-of-an-array-at-compile-time


가변 크기 배열을 구현하는 것이 더 복잡한 이유를 이해하려면 자동 저장 기간 ( "local") 변수가 일반적으로 어떻게 구현되는지에 대해 알아야합니다.

지역 변수는 주로 런타임 스택에 저장됩니다. 스택은 기본적으로 지역 변수에 순차적으로 할당되고 현재 "최고 수위"를 가리키는 단일 인덱스로 할당되는 큰 메모리 배열입니다. 이 인덱스는 스택 포인터 입니다.

함수가 입력되면 스택 포인터는 한 방향으로 이동되어 스택에 로컬 변수에 대한 메모리를 할당합니다. 함수가 종료되면 스택 포인터는 반대 방향으로 다시 이동하여 할당을 해제합니다.

즉, 메모리에있는 로컬 변수의 실제 위치는 함수 엔트리 1 의 스택 포인터 값을 기준으로 정의됩니다 함수의 코드는 스택 포인터의 오프셋을 통해 로컬 변수에 액세스해야합니다. 사용되는 정확한 오프셋은 로컬 변수의 크기에 따라 다릅니다.

모든 로컬 변수가 컴파일 타임에 고정 된 크기를 가질 때 스택 포인터의 오프셋도 고정되어 컴파일러가 내보내는 명령에 직접 코딩 할 수 있습니다. 예를 들어,이 함수에서 :

void foo(void)
{
    int a;
    char b[10];
    int c;
}

a는 STACK_POINTER + 0로 액세스 할 수 있으며 b는 STACK_POINTER + 4로 액세스 할 수 있고c는 STACK_POINTER + 14로 액세스 할 수 있습니다 .

그러나 가변 크기 배열을 도입하면 이러한 오프셋은 컴파일 타임에 더 이상 계산할 수 없습니다. 그 중 일부는 함수를 호출 할 때 배열이 갖는 크기에 따라 달라집니다. 이로 인해 컴파일러 작성자는 훨씬 복잡한 작업을 수행해야합니다. STACK_POINTER + N을 통해 액세스 해야 하는데, 그 N자체가 가변적이기 때문에 또 어딘가에 저장해둬야합니다. 이는 두 개의 액세스를 수행하는 것을 의미합니다. 하나는 STACK_POINTER + <constant>로드 N이고 다른 하나는 관심있는 실제 로컬 변수를 로드하거나 저장하는 것입니다.


1. 사실, "함수 엔트리에서의 스택 포인터의 값"은 그 자체로 유용한 값이라, 프레임 포인터 라는 이름을 가지고 있으며 많은 CPU는 프레임 저장 전용의 별도의 레지스터를 제공합니다. 실제로는 로컬 변수의 위치를 ​​계산하는 것은 일반적으로 스택 포인터 자체가 아닌 프레임 포인터가 하는 일입니다.

'프로그래밍 > C, C++ 공부' 카테고리의 다른 글

이중배열, N중배열  (0) 2018.02.17
배열의 이름  (0) 2018.02.16
정수의 자릿수 구하기, 한 자리씩 판별하기  (0) 2018.02.16
for문을 사용할 때  (0) 2018.02.15
The C++ Programming language의 조언들  (0) 2016.05.31