포인터 문법에 관한 고찰
-----------------------------------------
int array[10];
int *ptr = array;
-----------------------------------------
2번째 라인을 int *ptr = &array;로 바꾸어 컴파일하면 에러가 발생합니다.
array는 포인터 상수로, &array와 같은 주소값을 가짐에도 불구하고 말입니다.
이유가 무엇일까요?
아주 예전에 제가 위의 문제로 고민을 한적이 있었습니다. 하하.
우리가 생각한대로 int *ptr = &array가 되어야 합리적으로 보여질 수 있습니다.
하지만 다음과 같은 에러를 출력하는 것을 보실 수 있습니다.
'initializing' : cannot convert from 'int (*)[10]' to 'int *'
참 이상하죠? 배열명 array 자체는 주소값을 의미하고 거기에 단지 &연산을 했을 뿐인데 말입니다.
독자는 분명히 array == &array 라는 사실을 의심치 않을 겁니다.
왜냐하면, printf( "%x", array ); 와
printf( "%x", &array ); 이 같고,
printf( "%d", sizeof(array) ); 와
printf( "%d", sizeof(&array) ); 가 같은데 말이죠.
즉, 대상체가 의미하는 주소값과 대상체의 크기는 모두 동일하다는 것입니다.
그럼 다시 위의 에러를 살펴 봅시다.
[배열 포인터]형을 [포인터]형으로 변환이 불가능하다는 의미가 될 겁니다.
그래서 다시, int (*ptr)[10] = &array; 해서 컴파일 해 보았습니다.
에러없이 컴파일이 잘 되는군요. 하지만 상식적으로 저 역시 이해가 되질 않습니다.
여전히 의문을 가질 수 밖에 없었습니다. 그렇다면 좀 더 시각을 달리해보는건 어떨까
합니다. 배열명 array는 우리가 알고 있는대로 [포인터 상수]입니다.
배열명 자체가 주소값을 의미합니다. 그렇다면 상수에 &연산이 가능하다는 것조차도
논리적으로 좀 이상하지 않겠습니까?
&연산은 변수의 선두 번지를 구하는 연산이라는 것을 독자들도 잘 아실 겁니다.
그렇지만 &연산은 가능합니다. 왜냐하면, printf( "%d", &array );가 무리없이 컴파일되니까
말입니다. 저는 사실 이것도 뭔가 찝찝하다고 생각하였는데 독자가 동의하실지 모르겠습니다.
상수에 &연산을 허용한다는 것은 결국 &(&array)도 허용해야 하지 않겠습니까?
하지만 이것은 컴파일 에러를 출력합니다. '&' requires l-value로 말이죠.
(VC++로 컴파일하였을 때 기준)
하지만 다른 여러 컴파일러에서는 int *ptr = &array;가 허용되는 것으로 알고 있습니다.
(리눅스의 gcc가 허용하는 것으로 알고 있습니다)
우리들이 의도하신대로 말이죠. 제가 말하고 싶은 결론은 컴파일러의 Dependent한 문제라고
볼 수 밖에 없습니다. 항상 우리가 생각하는 논리와 의도대로 모든 문법이 구성이 되어있지 않
습니다. 저 역시 이 부분은 개인적으로 굉장히 아쉬운 부분으로 생각하고 있습니다.
결국은 컴파일러 문제죠. 여기까지는 컴파일러가 정한 문법 규칙이라고 밖에 볼 수 없습니다.
제가 그렇게 확신하는 이유가 다음의 Disassembling 코드때문입니다.
9: printf( "%d\n", array );
0040D76B lea eax,[ebp-28h]
0040D76E push eax
0040D76F push offset string "%d" (0042201c)
0040D774 call printf (0040d6c0)
0040D779 add esp,8
10: printf( "%d\n", &array );
0040D77C lea ecx,[ebp-28h]
0040D77F push ecx
0040D780 push offset string "%d" (0042201c)
0040D785 call printf (0040d6c0)
0040D78A add esp,8
같은 Addressing Mode로 연산을 한다는 사실을 위의 코드로 증명하였습니다.
( [확장자 .c]로 하여 int *ptr = &array; 컴파일하면 에러는 나지 않고 경고만 출력하더군요. )
컴파일러에 의해서 어쩔수 없는 부분은 그려려니 인정하고 이해보다는 암기하여
사용할 수 밖에 없다는 것이라고 생각합니다.
Written By Sim-Hyeon, Choe