C99

Tags:

http://zdnet.co.kr/techupdate/lecture/etc/0,39024989,39130477,00.htm
http://www.zdnet.co.kr/techupdate/lecture/etc/0,39024989,39131011,00.htm
http://zdnet.co.kr/techupdate/lecture/etc/0,39024989,39131659,00.htm

Struct Hack

유연한 배열 멤버[Lang][Open] 
구조체를 선언하되 구조체의 멤버 중 하나가 배열이고, 또 이 배열의 크기를 동적 할당을 통해 늘리거나 줄이고 싶다면 보통 다음 중 한 가지 방법을 통해 자료 구조를 구현하는 것이 일반적이다(이를 struct hack이라고 부른다). 

struct foo { 
   int number; 
   double bar[100]; 
} *flexible; 

flexible = malloc( 
   sizeof(struct foo) 
   – sizeof(double) * 100
   + sizeof(double) * n); 

flexible->number = n; 
flexible->bar[n-1] = 0;   // wrong

———————————— 

struct foo { 
   int number; 
   double bar[1]; 
} *flexible; 

flexible = malloc( 
   sizeof(struct foo) + 
   sizeof(double) * (n-1)); 

flexible->number = n; 
flexible->bar[n-1] = 0;   // wrong

이와 같은 프로그램 구조는 상당히 긴 기간 동안 다양한 C 프로그램에서 빈번하게 사용되어온 구조임에도 불구하고, 표준 C 언어를 엄격한 환경에도 무리 없이 적용할 수 있도록 허용하기 위해 모두 잘못된 구조로 규정했다. 위원회는 좌측 구조가 잘못된 이유를 일부 환경에서 구조체에 접근할 때 선언된 구조체형의 메모리 전체(bar[n]이 아닌 bar[100] 전부)를 요구할 수 있기 때문이며, 우측 구조가 잘못된 이유는 멤버 bar를 통해 일어나는 포인터 연산을 선언된 구조체형(bar[n]이 아닌 bar[1])에 맞춰 제한할 수 있기 때문이라고 설명하고 있다. 

결국 C99 이전에 위와 같은 형태의 자료 구조를 구성하는 유일한 적법한 방법은 다음과 같이 포인터를 사용해 번거로운 메모리 할당 과정을 거치는 것뿐이었다. 메모리 할당 과정이 번거롭다는 것은 그렇게 할당받은 메모리를 해제할 때도 동일하게 번거로움을 의미한다. 

struct foo { 
   int number; 
   double *bar; 
} *flexible; 

flexible = malloc(sizeof(struct foo)); 
flexible->bar = malloc(sizeof(double) * n); 
flexible->bar[n-1] = 0; 

하지만 표준화 위원회 역시 유연한 배열 멤버를 갖는 구조체를 처음 보인 것처럼 간단한 메모리 할당으로 구성될 수 있도록 할 필요가 있음을 동감했기에 C99에서 서둘러 다음과 같은 적법한 형태를 도입하게 된다. 

struct foo { 
   int number; 
   double bar[];   // flexible array member
} *flexible; 

flexible = malloc(sizeof(struct foo) + sizeof(double)*n); 
flexible->bar[n-1] = 0; 

비록 유연한 배열 멤버는 구조체의 마지막 멤버로서만 존재할 수 있다는 등의 다소 엄격한 제약과 유연한 배열 멤버를 갖는 구조체형에 적용되는 sizeof 연산자의 결과 등을 따로 정의하기 위해 언어를 이해하기가 다소 어려워졌지만, 앞서 보인 간단한 예를 통해 확인할 수 있듯이 새로 도입된 기술은 그 의도가 프로그램 상에서 분명히 드러나고 사용하기도 충분히 편리함을 확인할 수 있다. 

음 이게 널리 쓰이는 idiom이었군요.
엽기적이지만 대강 이해하면서 코드는 보고 있었지만, 처음으로 소개글을 봄.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *