Perbedaan antara size_t dan std :: size_t


143

Apa perbedaan antara size_tdan std::size_tdalam hal di mana mereka dideklarasikan, kapan harus digunakan dan fitur pembeda lainnya?


Saya tertarik untuk mengetahui apakah spesifikasi C ++ menghubungkan std :: size_t ke tipe C size_t.
Doug T.

Lihat pertanyaan serupa: link
Mankarse

Jawaban:


91

C size_tdan C ++ std::size_tkeduanya sama.

Di C, itu didefinisikan dalam <stddef.h>dan di C ++, itu didefinisikan <cstddef>yang isinya sama dengan header C (lihat kutipan di bawah). Its didefinisikan sebagai tipe unsigned integer dari hasil dari sizeof operator.

C Standard mengatakan dalam §17.7 / 2,

size_t yang merupakan tipe integer unsigned dari hasil dari sizeof Operator

Dan C ++ Standard mengatakan (tentang cstddefheader) di §18.1 / 3,

Kontennya sama dengan header pustaka C Standar, dengan perubahan berikut ini .

Jadi ya, keduanya sama; satu-satunya perbedaan adalah bahwa C ++ mendefinisikan size_tdi stdnamespace.

Harap perhatikan juga bahwa baris di atas juga mengatakan "dengan perubahan berikut" yang tidak mengacu pada size_t. Ini lebih mengacu pada penambahan baru (kebanyakan) yang dibuat oleh C ++ ke dalam bahasa (tidak ada di C) yang juga didefinisikan di header yang sama.


Wikipedia memiliki info yang sangat bagus tentang jangkauan dan ukuran penyimpanan size_t:

Rentang dan ukuran penyimpanan size_t

The aktual jenis size_t adalah tergantung platform ; sebuah kesalahan umum adalah dengan mengasumsikan size_t adalah sama dengan int unsigned, yang dapat menyebabkan kesalahan pemrograman, [3] [4] ketika bergerak dari 32 ke arsitektur 64-bit, misalnya.

Menurut standar ISO C 1999 (C99), size_t adalah jenis bilangan bulat unsigned setidaknya 16 bit.

Dan selebihnya Anda dapat membaca dari halaman ini di wikipedia.


Itu membawa ke Q lain, Jika STL sudah mengimpor size_t melalui C (cstddef) mengapa ia memiliki versi lain lagi?
Alok Save

43
@Als: Sebenarnya, ini adalah kesalahan untuk mengatakan size_ttanpa using namespace std;atau using std::size_t;. Namun, sebagian besar kompiler mengizinkannya, dan Standar secara khusus mengizinkan mereka untuk mengizinkannya (§D.5 / 3).
Potatoswatter

9
@ Potatoswatter: Tentunya itu tidak bisa menjadi kesalahan dan secara khusus diperbolehkan dalam standar? Kalau sudah standar, itu bukan error!
Ben Hymers

9
@BenHymers Standar menentukan apa yang dideklarasikan oleh header standar, dan mereka tidak diperbolehkan untuk mendeklarasikan nama non-reserved lainnya. Header <cstddef>mungkin atau mungkin tidak mendeklarasikan ::size_t, jadi Anda tidak bisa mengandalkannya ada atau tidak ada, kecuali secara khusus menyertakan <stddef.h>atau header lain dari pustaka C yang dijamin untuk mendeklarasikannya.
Potatoswatter

4
@Potatoswatter: Ah, saya mengerti apa yang Anda maksud sekarang! Saya pasti bingung dengan terlalu banyak kata "allow" dalam satu kalimat. Saya masih berpikir komentar pertama Anda terlalu kuat; seperti yang baru saja Anda katakan, ::size_tada misalnya di <stddef.h>, jadi Anda tidak selalu perlu membuatnya memenuhi syarat std::.
Ben Hymers

16

Dari C ++ 03 "17.4.3.1.4 Jenis":

Untuk setiap tipe T dari pustaka C Standar (catatan kaki 169), tipe :: T dan std :: T dicadangkan untuk implementasi dan, bila ditentukan, :: T harus identik dengan std :: T.

Dan catatan kaki 169:

Jenis ini adalah clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t, dan wint_t.


Jadi kode portabel tidak harus bergantung pada std::Tvarian yang ditentukan?
Mankarse

6
@Mankarse: Anda tidak boleh mengandalkan definisi mereka jika Anda hanya menyertakan versi C dari header yang sesuai. Jika Anda #include <stddef.h>kemudian std::size_tmungkin atau mungkin tidak tersedia. Jika Anda #include <cstddef>kemudian std::size_ttersedia, tetapi size_tmungkin tidak.
Dennis Zickefoose

4
@Mankarse: Lawannya. Header versi C ++ harus mendefinisikannya dalam std::dan paragraf mengatakan bahwa ia juga dapat mendefinisikannya di namespace tingkat atas dan jika ya, ia harus mendefinisikannya secara identik di dalam std::dan tingkat atas. Sebagian besar kompiler hanya menyertakan header C dan mengimpor nama ke std::, sehingga simbol akhirnya ditentukan di keduanya.
Jan Hudec

4
Secara pribadi, saya tidak pernah peduli dengan <cxxxxx> header atau std::varian pengenal yang berasal dari pantai C. Saya tetap menggunakan <xxxxx.h>untuk header C standar - itu tidak pernah menjadi masalah. Jadi, saya akan menggunakan <stddef.h>dan size_tdan tidak pernah berpikir dua kali untuk std::size_t; pada kenyataannya, tidak pernah terlintas dalam pikiran saya bahwa ada (atau mungkin) a std::size_t.
Michael Burr

14

std :: size_t sebenarnya stddef.h 's size_t .

cstddef memberikan yang berikut:

#include <stddef.h>
namespace std 
{
  using ::ptrdiff_t;
  using ::size_t;
}

... secara efektif membawa definisi sebelumnya ke namespace std.


Seperti yang ditunjukkan Nawaz, sebenarnya yang terjadi adalah sebaliknya. Anda tidak dapat memasukkan <cstddef>dan mengharapkan untuk mendapatkan ::size_t, tetapi jika Anda memasukkan <stddef.h>Anda akan mendapatkan std::size_t.
MSalters

4
@ MSalters, saya tidak mengikuti. Termasuk <stddef.h>hanya akan membuatmu ::size_t.
hifier

2
Itu adalah bug dalam implementasi Anda.
MSalters

4
@ MSalters, saya kurang mengikuti. Bukankah seharusnya sebaliknya? <cstddef> berasal dari C ++, jadi harus mendefinisikan hal-hal di std :: *? Di sisi lain, dalam header C, seperti stddef.h, saya hanya mengharapkan tipe C, yaitu :: size_t.
Ela782

12
@MSalters, karena C ++ 11 itu tidak akurat. Jika Anda memasukkan <cstddef>Anda dijamin untuk mendapatkan std::size_tdan Anda mungkin juga mendapatkan ::size_t(tapi itu tidak dijamin). Jika Anda memasukkan <stddef.h>Anda dijamin akan mendapatkan ::size_tdan Anda mungkin juga mendapatkan std::size_t(tapi itu tidak dijamin). Itu berbeda di C ++ 03 tetapi itu secara efektif tidak dapat diterapkan dan diperbaiki sebagai cacat.
Jonathan Wakely
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.