핵심 요약
- C 언어의 배열 타입은 메모리상 연속된 공간을 나타내지만, 표현식과 함수 매개변수에서 첫 번째 요소를 가리키는 포인터로 자동 변환(decay)됩니다.
- `sizeof` 연산자 등에서만 예외적으로 원래 크기가 반환되는 등 일관성 없는 동작 때문에 초보자들에게 큰 혼란을 줍니다.
- 작성자는 배열이 구조체처럼 값(value) 기반으로 엄격히 분리되어 동작했다면 훨씬 직관적이었을 것이라고 지적합니다.
요약 C 언어에서 배열 타입 `T[n]`은 메모리상에 연속된 n개의 T 값을 나타내지만, 실제 코드에서는 표현식에 쓰이는 즉시 첫 번째 요소를 가리키는 포인터(`T *`)로 자동 변환(decay)됩니다. 이 때문에 배열 인덱스 연산(`arr[ix]`)조차 내부적으로 `*(arr + ix)`처럼 포인터 연산으로 작동하여 개발자가 배열을 포인터처럼 다루게 만듭니다.
하지만 몇 가지 특수한 예외가 혼란을 가중시킵니다. 대표적으로 `sizeof arr`는 포인터 크기가 아니라 실제 배열 전체 크기(`sizeof(T) * n`)를 반환합니다. 반면 함수의 매개변수로 `T arr[n]` 형태를 넘기면 명시된 크기 n은 완전히 무시되고 포인터로 강제 변환되어, 함수 내부에서의 `sizeof`는 배열 크기가 아닌 포인터 크기만을 반환하게 됩니다. 크기 정보를 유지하려면 복잡한 포인터-배열 문법(`T (*)[n]`)을 써야 하는 불편함이 따릅니다.
작성자는 이러한 암시적 변환 대신 C 언어가 구조체(struct)처럼 배열과 포인터를 엄격히 분리했어야 한다고 주장합니다. 배열을 값(Value)으로 취급해 함수 인자로 넘길 때 전체 복사가 일어나도록 만들면, 초보자가 흔히 겪는 참조 전달 관련 혼란을 크게 줄일 수 있다는 분석입니다. 비록 매번 복사가 발생한다는 단점이 있지만, 프로그래머에게 명확한 선택권을 주고 컴파일러 최적화로 보완할 수 있는 등 훨씬 직관적인 언어 모델이 되었을 것이라는 의견을 제시했습니다.
Sponsored · 광고