C 배열의 구현 학술

Fun code
int main (int argc, const char * argv[])
{
int a[3] = { 100, 200, 300 };
int b = 2;
int *c = &a[b];

printf("%d\n", b[a]);
printf("%d\n", c[-1]);

return 0;
}

C 컴파일러를 만들어봤으면 예측할 수 있다.
어차피 만드는 놈이 그 놈이 그 놈이거덩 ㅋㅋㅋ

저것들이 스캐너로 들어가고 AST를 만들고 나면 타입 정보가 차곡차곡 쌓여있긴 한데.
잠시 문법을 무시하고 b[a]을 순전히 만드는 놈 입장에서 생각해보자.
b 포인터가 담은 주소값에 a의 타입의 크기와 인덱스를 곱해서 더해야 주소값이 나온다.

포인터라고는 하지만 어차피 주소를 담은 변수일 뿐이다.
그냥 b 위치의 값을 읽어오는 어셈블리 코드를 내뱉은 다음
(a x 타입 정보에서 끄집어 낸 크기)를 더하는 어셈블리 코드를 내뱉고
그 메모리 주소를 로드하도록 어셈블리 코드를 내뱉게 된다.

그런고로 b[a]라고 해도 a[b]와 결과가 다르지 않게 된다.
c[-1]도 같은 맥락에서 이해하면 된다.

근데 gcc는 경고조차 따로 없는걸 보면..
스펙에서는 원래 a[b]나 b[a]나 따로 구분하지 않는건가?;;

트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://xeraph.com/tb/3206452 [도움말]

덧글

  • MacApps 2007/03/17 01:52 # 답글

    컴파일된 어셈블리 코드를 들여다봐도 힌트가 있죠. :)
    스팩에서 해당 사항이 있나 찾다가 포기했었는데요, C계열 컴파일러가 이러면에서는 조금 엉성한 느낌을 주게 만드는 면이 있는것 같습니다. 내부 구현이야 그렇다 치더라고 고급언어에서 a[b]와 b[a]를 같이 취급해버린 다는 것은... 아무래도 C가 비교적 로레벨한 고급언어(?)라서 그런가보다 하고 있습니다.

    참, 경고는 gcc뿐만 아니라 Visual C++도 역시 경고를 내지 않더군요. 다른 컴파일러들은 어떨지 모르겠네요.
  • Cicero 2007/03/17 05:25 # 답글

    C스펙에 a[b]가 *(a+b)의 equivalent expression이라는 거 외에 별다른 constraint는 없었던 걸로 기억을; (본지가 백만년이라 확실하진 않-_-)
    + operator가 int+pointer에 대해 정의되어 있으니 별로 이상할 건 없지.
  • 홈쥬인 2007/03/17 09:25 # 답글

    c++ 컴파일러로 컴파일해바 -_-
    잔소리가 많이 늘어날거야 ...
    잔소리 안 듣는 맛에 C 쓰는거야 -_-... (가끔 이유없이 뻗을땐 나도 잘 모르겠..)
댓글 입력 영역