Fun code
C 컴파일러를 만들어봤으면 예측할 수 있다.
어차피 만드는 놈이 그 놈이 그 놈이거덩 ㅋㅋㅋ
저것들이 스캐너로 들어가고 AST를 만들고 나면 타입 정보가 차곡차곡 쌓여있긴 한데.
잠시 문법을 무시하고 b[a]을 순전히 만드는 놈 입장에서 생각해보자.
b 포인터가 담은 주소값에 a의 타입의 크기와 인덱스를 곱해서 더해야 주소값이 나온다.
포인터라고는 하지만 어차피 주소를 담은 변수일 뿐이다.
그냥 b 위치의 값을 읽어오는 어셈블리 코드를 내뱉은 다음
(a x 타입 정보에서 끄집어 낸 크기)를 더하는 어셈블리 코드를 내뱉고
그 메모리 주소를 로드하도록 어셈블리 코드를 내뱉게 된다.
그런고로 b[a]라고 해도 a[b]와 결과가 다르지 않게 된다.
c[-1]도 같은 맥락에서 이해하면 된다.
근데 gcc는 경고조차 따로 없는걸 보면..
스펙에서는 원래 a[b]나 b[a]나 따로 구분하지 않는건가?;;
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]나 따로 구분하지 않는건가?;;




덧글
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 쓰는거야 -_-... (가끔 이유없이 뻗을땐 나도 잘 모르겠..)