const int SZ = 1000;
int arr[SZ];

위의 코드는 오류없이 잘 실행되는 코드다.

int a = 1000;
const int SZ = a;
int arr[SZ];

하지만 이 코드는 컴파일 에러가 발생하는 코드다. 왜일까?

배열의 크기는 컴파일 타임에 정해져야 하므로 상수가 와야 한다. 첫번째 코드는 정수 리터럴을 때려 박았으므로 SZ의 값을 이미 알고 있다. 따라서, 컴파일 타임에 arr의 크기를 추적하는 것이 가능하다.

하지만 두번째 코드는 그렇지 않다. a는 변수이므로 a의 값이 얼마일지는 컴파일 타임에 추적할 수 없다. 뭐 지금이야 코드가 짧으니까 'a 값은 1000이고, 그럼 SZ 값은 1000이고, arr의 크기를 알 수 있는 것 아니냐?' 하고 반론을 제기할 수도 있다. 하지만 다음과 같은 상황이면 어떤가?

int a = 10;
int b = a * a + 3;
int c = 0;
for (int i = 0; i < 10; ++i) c += b;
const int SZ = c + 10;
int arr[SZ];

a 값은 10이고, b 값은 103이고, c 값은 1030이고, 그럼 SZ 값은 1040이 된다. 이걸 과연 컴파일 타임에 전부 계산해서 SZ의 값을 구해야 할 의무가 있을까? 이건 런타임의 영역이지, 컴파일 타임의 영역이 아니다. 즉, 변수의 값을 const 변수에 대입하는 것부터 컴파일 타임에 정할 수 없다고 생각하여 에러를 내는 것이다.

Reference