Apa perbedaan antara size_t dan int di C ++?

173

Dalam beberapa contoh C ++ saya melihat penggunaan tipe di size_tmana saya akan menggunakan yang sederhana int. Apa bedanya, dan mengapa size_tharus lebih baik?

tunnuz
sumber
3
Untuk contoh aktual di mana mereka tidak dapat dipertukarkan, lihat pertanyaan yang saya tanyakan sebelumnya: stackoverflow.com/questions/645168/…
Tyler McHenry

Jawaban:

153

Dari Wikipedia yang ramah :

File header stdlib.h dan stddef.h menentukan tipe data yang disebut size_t yang digunakan untuk mewakili ukuran objek. Fungsi pustaka yang mengambil ukuran mengharapkannya dari tipe size_t, dan sizeof operator mengevaluasi ke size_t.

Jenis sebenarnya dari size_t tergantung pada platform; kesalahan umum adalah menganggap size_t sama dengan unsigned int, yang dapat menyebabkan kesalahan pemrograman, terutama karena arsitektur 64-bit menjadi lebih umum.

Juga, periksa Mengapa size_t penting

Joao da Silva
sumber
76
Jadi, apa itu size_t?
NDEthos
8
@NDEthos Tergantung! Pada ini di sini Linux /usr/include/stdlib.hmendapatkan definisi dari /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hdan di dalamnya default untuk long unsigned intkecuali beberapa file header lainnya mengatakan sebaliknya.
David Tonhofer
1
Saya mengkonfirmasi size_t ke tuncation berbahaya . Ini mungkin di luar topik, tetapi bagaimana menulis tambalan sendiri untuk memperbaiki kesalahan semacam itu ketika muncul ribuan kali di kernel linux?
user2284570
36

size_t adalah tipe yang digunakan untuk merepresentasikan ukuran (sesuai namanya). Platformnya (dan bahkan berpotensi implementasi) bergantung, dan harus digunakan hanya untuk tujuan ini. Jelas, mewakili ukuran, size_t tidak ditandatangani. Banyak fungsi stdlib, termasuk malloc, sizeof dan berbagai fungsi operasi string menggunakan size_t sebagai datatype.

Int ditandatangani secara default, dan meskipun ukurannya juga tergantung platform, itu akan menjadi 32bits tetap pada kebanyakan mesin modern (dan meskipun size_t 64 bit pada arsitektur 64-bit, int tetap 32bit lama pada arsitektur tersebut).

Untuk meringkas: gunakan size_t untuk mewakili ukuran objek dan int (atau panjang) dalam kasus lain.

Axelle Ziegler
sumber
12

The size_tjenis didefinisikan sebagai jenis terpisahkan unsigned dari sizeofoperator. Di dunia nyata, Anda akan sering melihat intdidefinisikan sebagai 32 bit (untuk kompatibilitas mundur) tetapi size_tdidefinisikan sebagai 64 bit (sehingga Anda dapat mendeklarasikan array dan struktur lebih dari 4 GiB dalam ukuran) pada platform 64-bit. Jika a long intjuga 64-bit, ini disebut konvensi LP64; jikalong int 32 bit tetapi long long intdan pointer 64 bit, itu LLP64. Anda juga mungkin mendapatkan kebalikannya, sebuah program yang menggunakan instruksi 64-bit untuk kecepatan, tetapi pointer 32-bit untuk menghemat memori. Juga, intditandatangani dan size_ttidak ditandatangani.

Secara historis ada sejumlah platform lain di mana alamat lebih luas atau lebih pendek dari ukuran asli int. Pada kenyataannya, di tahun 70-an dan awal 80-an, ini lebih umum daripada tidak: semua mikrokomputer 8-bit yang populer memiliki register 8-bit dan alamat 16-bit, dan transisi antara 16 dan 32 bit juga menghasilkan banyak mesin yang memiliki alamat yang lebih luas daripada register mereka. Saya kadang-kadang masih melihat pertanyaan di sini tentang Borland Turbo C untuk MS-DOS, yang mode memori Huge memiliki 20-bit alamat disimpan dalam 32 bit pada CPU 16-bit (tetapi yang dapat mendukung set instruksi 32-bit dari 80386); Motorola 68000 memiliki ALU 16-bit dengan register dan alamat 32-bit; ada mainframe IBM dengan alamat 15-bit, 24-bit atau 31-bit. Anda juga masih melihat berbagai ukuran ALU dan address-bus dalam sistem embedded.

Setiap saat intlebih kecil dari size_t, dan Anda mencoba untuk menyimpan ukuran atau offset dari file atau objek yang sangat besar dalam suatu unsigned int, ada kemungkinan itu bisa meluap dan menyebabkan bug. Dengan int, ada juga kemungkinan mendapatkan angka negatif. Jika suatu intatauunsigned int lebih lebar, program akan berjalan dengan benar tetapi membuang-buang memori.

Anda biasanya harus menggunakan tipe yang benar untuk tujuan tersebut jika Anda menginginkan portabilitas. Banyak orang akan merekomendasikan agar Anda menggunakan matematika yang ditandatangani alih-alih tidak ditandatangani (untuk menghindari bug yang jahat dan halus 1U < -3). Untuk tujuan itu, mendefinisikan perpustakaan standar ptrdiff_tdi <stddef.h>sebagai jenis ditandatangani hasil mengurangkan pointer dari yang lain.

Yang mengatakan, solusi mungkin untuk batas-memeriksa semua alamat dan penyeimbang terhadap INT_MAXdan salah satu 0atau yang INT_MINsesuai, dan nyalakan peringatan kompiler tentang membandingkan jumlah yang ditandatangani dan tidak ditandatangani jika Anda kehilangan. Anda harus selalu, selalu, selalu memeriksa akses array Anda untuk limpahan dalam C.

Davislor
sumber
8

Itu karena size_t bisa berupa apa saja selain int (mungkin struct). Idenya adalah bahwa itu memisahkan pekerjaan itu dari tipe yang mendasarinya.

graham.reeds
sumber
8
Saya pikir size_t sebenarnya dijamin menjadi alias untuk integer yang tidak ditandatangani, jadi tidak bisa menjadi struktur. Saya tidak memiliki referensi yang berguna untuk mendukung ini sekarang.
bersantai
9
@unwind: C99: TC3, 7.17 §2
Christoph
1
@danio Kenapa begitu? bisakah Anda menjelaskan?
Rüppell's Hering
2
Saya tidak akan menautkan ke cplusplus jika saya adalah Anda! Jika Anda tidak dapat mengutip pasal, ayat, paragraf dan kalimat maka itu semua hanya desas-desus! :-)
graham.reeds
1
size_tditetapkan sebagai tipe integer yang tidak ditandatangani . C11 §6.5.3.4 5 "Nilai hasil dari kedua operator ( sizeof _Alignof) adalah yang ditentukan implementasi, dan tipenya (tipe integer yang tidak ditandatangani) adalah size_t,".
chux - Reinstate Monica
-1

Definisi SIZE_Tini ditemukan di: https://msdn.microsoft.com/en-us/library/cc441980.aspx dan https://msdn.microsoft.com/en-us/library/cc230394.aspx

Menempel di sini informasi yang diperlukan:

SIZE_Tadalah ULONG_PTRjumlah maksimum byte yang dapat ditunjukkan oleh sebuah pointer.

Jenis ini dinyatakan sebagai berikut:

typedef ULONG_PTR SIZE_T;

SEBUAH ULONG_PTR adalah tipe panjang tanpa tanda yang digunakan untuk presisi pointer. Ini digunakan ketika casting pointer ke tipe panjang untuk melakukan aritmatika pointer.

Jenis ini dinyatakan sebagai berikut:

typedef unsigned __int3264 ULONG_PTR;
sundar
sumber
2
SIZE_Tbukan size_t, apa yang ditanyakan OP.
ikegami
2
Itu ekstensi Microsoft, bukan bagian dari bahasa standar.
Davislor
SIZE_Tsama sekali berbeda dari size_t. Anda tidak dapat mendeklarasikan variabel tipe SIZE_T.
calocedrus