Re: 구조체 포인터의 크기
, 도장_ 관리자님이 작성온라인 컴파일러에 좀 더 정확하게 오류를 표기하게 옵션을 지정했습니다.
https://glot.io/snippets/flvejzb7cf
왼쪽 상단 C 아이콘을 클릭하면 컴파일러 옵션을 확인할 수 있습니다. clang, gcc 모두 공통입니다.
clang main.c -Wall -ansi -pedantic -std=c11 && ./a.out
gcc main.c -Wall -ansi -pedantic -std=c11 && ./a.out
8 8 8
main.c:11:24: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat] printf("%d %d %d", sizeof(char*), sizeof(int*), sizeof(struct Point2D*)); ~~ ^~~~~~~~~~~~~ %lu main.c:11:39: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat] printf("%d %d %d", sizeof(char*), sizeof(int*), sizeof(struct Point2D*)); ~~ ^~~~~~~~~~~~ %lu main.c:11:53: warning: format specifies type 'int' but the argument has type 'unsigned long' [-Wformat] printf("%d %d %d", sizeof(char*), sizeof(int*), sizeof(struct Point2D*)); ~~ ^~~~~~~~~~~~~~~~~~~~~~~ %lu 3 warnings generated.
%lu를 써야 합니다.
%d로도 결과가 출력되는 건 sizeof의 결과를 암묵적으로 int 형으로 변환하기 때문입니다.
사용하는 컴파일러에서 옵션을 지정하고 시도해보세요.
오류가 없게 하려면 포인터의 크기를 출력할 때 32비트 플랫폼에서는 %u를 써야 하고, 64비트 플랫폼에서는 %lu를 써야 합니다.
포인터의 크기가 고정되어 있고, 값이 4 또는 8인 경우가 대부분이라서 %d int 타입으로 변환해도 오류가 발생하는 경우는 없습니다.
포인터의 크기는 플랫폼에서 지정합니다.
32비트 플랫폼이면 대부분의 경우에 4바이트이고,
64비트 플랫폼이면 대부분의 경우에 8바이트입니다.
포인터는 메모리 주솟값을 다루는 것이므로 해당 플랫폼에서 다룰 수 있는 주솟값의 크기로 고정입니다.
따라서 앞서 답변에 언급한 참고와 같이 32비트, 64비트 환경이냐가 포인터의 크기를 정합니다.
64비트 환경에서 32비트로 컴파일하면 32비트 응용 프로그램으로 실행되기 때문에 포인터의 크기는 4바이트가 됩니다. 이 경우에는 컴파일러 옵션을 살펴봐야 합니다.
해당 사항도 참고에서 링크로 언급되어 있습니다.
더 정확하게는 C 언어에서 포인터의 크기는 플랫폼에 따른 메모리 모델에 따라 정해집니다. 이건 대다수 C 언어 사용자가 잘 모르는 내용이고, 고급 내용이기 때문에 부록에 정리되어 있습니다.
을 참고하세요.
사용하는 컴파일러가 버전이 낮을 수도 있고, 컴파일러 옵션이 정확하지 않아서 오류 메시지가 부정확할 수도 있습니다.