C는 상당히 까다로운 프로그래밍 언어다. 특히 언어 명세 과정에서 몇 가지 어두운 구석이 존재하기 때문에 깜짝 놀랄만한 결과를 실행 시점에서 얻고 대략 난감할 수도 있다. 먼저 So you think you know C?에 들어가서 문제를 풀어보자. 스포일러 방지를 위해 문제를 풀고 나서 스크롤 하시라!
문제를 다 푸시고 [See the score] 버튼을 누르면 채점표와 함께 아래에 해설이 나오는데 몇 가지 추가 설명을 드리겠다.
- 1번. 이 문제는 포인터를 조금만 알고 계시면 바로 맞출 수 있다. 32비트와 64비트에 따라 포인트 크기가 달라지므로 미정의가 된다.
- 2번. C에서는 아키텍처에 따라 타입마다 정해진 크기가 다를 수 있고, 형 변환 과정에서 어떻게 될지 모르므로 미정의가 된다.
- 3번. 이 문제는 너무 잘 알아도 틀리는 문제다. ' '가 십진수 32이며, 여기에 13을 곱하면 256을 넘어가므로 오버플로우가 발생할 것으로 예상해서 답을 -96으로 적고 싶지만... char 타입 크기를 정확하게 모른다는 문제가 있다. 따라서 미정의가 된다.
- 4번. 이 문제는 상당힌 트릭을 발휘하고 있어서 맞추는 분들이 적을 것이다. 하지만 컴파일러는 답을 알고 있다.
여기서 최신 gcc 컴파일러에서는 자체 비교는 항상 참이라는 경고가 나오는데(결국 어떻게 해도 참이 될 것이다), 구식 컴파일러는 int 크기로 인해 이해할 수 없는 상황을 맞이할 수 있다. - 5번. 이 문제는 워낙 유명해서 아마 많은 분들께서 맞추셨을 것이다.
여기서 시퀀스 포인트는 모든 식의 평가가 완료되는 지점이며, 시퀀스 포인트 사이에서 식의 값은 한 번만 수정될 수 있다. 이 문제는 시퀀스 포인트 사이에서 여러 차례 식의 값이 변경되므로 컴파일러 입장에서는 미정의가 된다.
그렇다고 C 프로그래밍이 몹쓸 언어라는 말은 아니다. 여러 가지 제약 사항을 알고, 플랫폼마다 차이가 난다는 사실을 이해하고 있으면 대부분 큰 문제없이 함정을 피할 수 있을 것이다.
EOB
흥미로운 주제인데 좀 속은 느낌도 드네요.ㅎㅎ
답글삭제