Standar C menjamin itu size_t
adalah tipe yang dapat menampung indeks array apa pun. Ini berarti bahwa, secara logis, size_t
harus dapat menahan semua jenis pointer. Saya telah membaca di beberapa situs yang saya temukan di Google bahwa ini legal dan / atau harus selalu berfungsi:
void *v = malloc(10);
size_t s = (size_t) v;
Jadi di C99, standar memperkenalkan intptr_t
dan uintptr_t
jenis, yang ditandatangani dan jenis yang tidak ditandatangani dijamin untuk dapat menahan pointer:
uintptr_t p = (size_t) v;
Jadi apa perbedaan antara menggunakan size_t
dan uintptr_t
? Keduanya tidak ditandatangani, dan keduanya harus dapat menahan jenis pointer apa pun, sehingga keduanya tampak identik secara fungsional. Apakah ada alasan kuat yang nyata untuk menggunakan uintptr_t
(atau lebih baik, a void *
) daripada a size_t
, selain kejelasan? Dalam struktur buram, di mana lapangan hanya akan ditangani oleh fungsi internal, adakah alasan untuk tidak melakukan ini?
Dengan cara yang sama, ptrdiff_t
telah menjadi tipe bertanda yang mampu menahan perbedaan pointer, dan karenanya mampu menahan sebagian besar pointer, jadi bagaimana bedanya intptr_t
?
Bukankah semua tipe ini pada dasarnya melayani versi yang berbeda dari fungsi yang sama? Jika tidak, mengapa? Apa yang tidak bisa saya lakukan dengan salah satu dari mereka yang saya tidak bisa lakukan dengan yang lain? Jika demikian, mengapa C99 menambahkan dua jenis dasarnya tidak berguna untuk bahasa?
Saya bersedia untuk mengabaikan fungsi pointer, karena mereka tidak berlaku untuk masalah saat ini, tetapi jangan ragu untuk menyebutkannya, karena saya memiliki kecurigaan menyelinap mereka akan menjadi pusat jawaban "benar".
size_t
danuintptr_t
tetapi bagaimanaptrdiff_t
danintptr_t
- tidakkah keduanya dapat menyimpan rentang nilai yang sama di hampir semua platform? Mengapa memiliki tipe integer berukuran pointer dan unsigned, terutama jikaptrdiff_t
sudah melayani tujuan dari tipe integer ukuran pointer yang ditandatangani.