Ответ 1
Потому что на многих 64 бит машинах (например, x86-64) для общего компилятора GCC sizeof(int)==4
, но sizeof(void*)==8 && sizeof(long)==8
; Это называется моделью данных I32LP64 (или просто LP64) .
Например, скомпилируйте и запустите следующую программу в системе Linux/x86-64:
#include<stdio.h>
#include<stdint.h>
int main ()
{
printf ("sizeof(int)=%d\n", (int) sizeof (int));
printf ("sizeof(intptr_t)=%d\n", (int) sizeof (intptr_t));
printf ("sizeof(short)=%d\n", (int) sizeof (short));
printf ("sizeof(long)=%d\n", (int) sizeof (long));
printf ("sizeof(long long)=%d\n", (int) sizeof (long long));
printf ("sizeof(void*)=%d\n", (int) sizeof (void *));
return 0;
}
После компиляции в моей системе с gcc -Wall s.c -o s
и запуском ./s
на моем процессоре Debian/Sid/x86-64 (i3770k GCC 4.8.2):
sizeof(int)=4
sizeof(intptr_t)=8
sizeof(short)=2
sizeof(long)=8
sizeof(long long)=8
sizeof(void*)=8
после компиляции в режиме 32 бит с использованием gcc -m32 -Wall s.c -o s32
и запуска ./s32
:
sizeof(int)=4
sizeof(intptr_t)=4
sizeof(short)=2
sizeof(long)=4
sizeof(long long)=8
sizeof(void*)=4
Я получаю тот же вывод, если компиляция для x32 с помощью gcc -mx32 -O3 -Wall s.c -o sx32
!
Кстати, возможно, лучший вопрос - почему бы не использовать intptr_t
.... Я понятия не имею (вероятно, вопрос привычек; когда Linus начал чтобы закодировать его ядро, C99 стандарт -defining <stdint.h>
и intptr_t
- еще не существовал).
Подробнее о ABI, в частности, внимательно прочитайте X86-64 ABI (см. также x32 ABI...) и wikipage на соглашениях x86.