Zero length array
글쓴이: pynoos / 작성시간: 화, 2003/09/23 - 1:40오후
Variable Length Array하고는 조금 다른 예인것 같습니다만,
gcc 의 extension 중에
array 크기를 0으로 주는 경우가 있습니다.
#include <stdio.h> int test1() { int a[0]; int b; b = 2; printf("%d %x %x %d\n", sizeof a, &a, &b, a[0] ); return 0; } int test2() { struct X { int a[0]; int b; } x; x.b = 2; printf("%d %x %x %d\n", sizeof x, &x.a, &x.b, x.a[0] ); return 0; } int main() { test1(); test2(); return 0; } $ ./a 0 bffff9a0 bffff99c -1073743400 4 bffff9a0 bffff9a0 2
일반 자동 변수들 사이에서는 zero length array 가 별 효력을 미치지 못합니다만.. struct 안에서는 재밌는 일을하는군요.
전에 linux 코드중에서 보았는데, variable length array를 흉내내는 일을 하는 것 같습니다. linux야 gcc 로만 compile 하니까 extension을 사용해도 무방하리라 봅니다만..
대충 웹에서 찾아보니..
http://www.iglu.org.il/lxr/source/fs/select.c
이 코드에 해당하는 것중에 poll_table_page 입니다.
제가 알고 있는 VLA 용도 외에 다른 것이 있나요?
Forums:
zero-length array를 허용하지 않는 것을 역이용하기
pynoos님의 말씀대로, zero-length array는 ANSI 표준에서는 허용하지 않으므로 gcc에서만 사용할 수 있습니다. (gcc에도 허용하지 않게하는 옵션이 있을텐데, 제가 지금 gcc가 없어서 모르겠네요.)
이러한 사실을 역으로 이용하면, 간편하게 compile-time assertion 기능을 만들 수 있습니다.
예를 들어, reinterpret_cast 형변환 연산을 좀 더 안전하게 수행하기 위해
어떤 타입이 자신의 크기보다 작은 타입으로 형변환하는 것을 막는
safe_reinterpret_cast 함수를 만든다고 생각해봅시다.
위에서 sizeof는 컴파일 타임 연산자인데, assert를 사용하면 런타임에 어서션이 발생합니다. 런타임이 아니면 에러가 발생하는 지를 알수가 없는 문제가 있죠.
바로 이와 같은 경우에 컴파일 타임 어서션이 필요합니다.
컴파일 타임에 sizeof(From) > sizeof(To)가 되는 경우는
크기가 0인 배열을 만들수 없다는 에러가 나면서 컴파일이 종료됩니다.
물론 컴파일 타임 어서션을 위해 zero-length array 금지 규칙외에 다른 기법을 사용할 수 있지만(에러메시지를 커스토마이징하기 위해), 한줄로 가장 짧게 구현할 수 있는 방법이긴 하죠.
C99 에서는 허용됩니다.
'C언어 펀더멘탈'...
구조체나 공용체의 마지막 member 가 배열일 경우 선언 시에 크기를 명시하지 않고 할당할 수 있다고 합니다.
VLA 를 구조체나 공용체의 member 로 쓸 수 있도록 하기 위해서겠죠.
Re: C99 에서는 허용됩니다.
저도 C99 의 그 문구가 위 코드와 관련있나 생각하고는 있는데,
크기를 명시하지 않은 것이 아니라, 0 이라 명시한 것이라...
관련 없는 사항이지 않나 싶습니다.
C99 에 포함된 것이 아니라 GCC 만의 extension이지 싶네요.
---
http://coolengineer.com
Re: C99 에서는 허용됩니다.
VLA 와 구조체, 공용체 멤버로서의 flexible array member 를 허락하는 것
에는 다소 기술적인 차이가 있습니다 - flexible array member 와 VLA 는
전혀 다른 문제 의식에서 시작된 것입니다. 물론, flexible array member
가 zero-size object 와 역사적으로 관련이 있었던 것은 사실입니다.
C 언어의 정의에는 zero-size object 를 허락하지 않는다는 원칙이 있습니
다. object 라는 용어의 정의 자체가 zero-size 를 배제하기 때문에,
zero-size object 를 허락한다면 C 표준 전체의 넓은 영역에 수정이 불가피
합니다. 물론, zero-size object 가 몇몇 실용적인 부분에서 유용하다는 것
은 위원회 멤버들도 인식하고 있습니다만, 다른 방법을 사용하면 표준에
conforming 한 프로그램으로 동일한 행동을 보이는 것이 가능하기에 고려
되지 않고 있습니다.
과거 zero-size object 가 구조체, 공용체 멤버의 flexible array member
구현을 위해 사용된 것은 사실이지만, C99 에서는 flexible array member
를 위한 별도의 기술을 추가하고 있기에 최소한 flexible array member 를
위한 필요성은 사라졌습니다. 참고로, C90 에서는 어떠한 방법을 통해서든
(즉, 더 적은 크기의 배열 대상체를 사용하든, 반대로 매우 넉넉한 크기의
배열 대상체를 사용하든) 유효한 flexible array member 를 구현할 수 있는
방법이 없습니다.
그럼...
--
Jun, Woong (woong at gmail.com)
http://www.woong.org
댓글 달기