Size_t ve std arasındaki fark :: size_t


139

Nerede beyan edildikleri, ne zaman kullanılmaları ve diğer ayırt edici özellikler arasındaki size_tve std::size_tarasındaki farklar nelerdir?


C ++ spec std :: size_t C size_t türüne bağlanırsa bilmek istiyorum.
Doug T.

Benzer soru: link
Mankarse

Yanıtlar:


88

C'ler size_tve C ++ 'lar std::size_taynıdır.

C'de, içeriği C başlığıyla aynı olan <stddef.h>C ++ 'da ve C ++' da tanımlanır <cstddef>(aşağıdaki alıntıya bakın). Onun olarak tanımlanan işaretsiz tamsayı türü bir sonucu ve sizeof operatörü.

C Standardı §17.7 / 2'de diyor,

size_t işaretsiz bir tamsayı tipi bir sonucu arasında sizeof operatörü

Ve C ++ Standardı cstddef§18.1 / 3'te ( başlık hakkında ) diyor ,

İçerik , aşağıdaki değişikliklerle Standart C kitaplığı üstbilgisiyle aynıdır .

Yani evet, ikisi de aynı; tek fark, C ++ ' size_tnın stdad alanında tanımlamasıdır .

Ayrıca, yukarıdaki satırda ayrıca "aşağıdaki değişikliklerle" ifadesi bulunmadığını da belirtin size_t. Daha çok C ++ tarafından aynı başlıkta da tanımlanan dile (C'de bulunmayan) yapılan yeni eklemelere atıfta bulunur.


Wikipedia, size_t'ın aralık ve depolama boyutu hakkında çok iyi bilgiye sahiptir:

Size_t aralığı ve depolama boyutu

Gerçek size_t türüdür platforma göre ; bir ortak bir hata , size_t programlama hatalara yol açabilir, işaretsiz int olarak olduğunu varsaymak [3] [4], örneğin, 64-bit mimarisi 32'den geçerken.

1999 ISO C standardına (C99) göre, size_t en az 16 bitlik işaretsiz bir tam sayı türüdür.

Ve geri kalanını wikipedia'da bu sayfadan okuyabilirsiniz .


Bu başka bir Q'ya getiriyor, STL zaten size_t'yi C (cstddef) üzerinden içeri aktarıyorsa, neden tekrar kendi başka bir sürümüne sahip?
Alok Kaydet

43
@Als: Kesinlikle söylemek gerekirse, veya size_tolmadan söylemek bir hatadır . Bununla birlikte, çoğu derleyici buna izin verir ve Standart özellikle izin verir (§D.5 / 3). using namespace std;using std::size_t;
Potatoswatter

9
@Potatoswatter: Kesinlikle bu bir hata olamaz ve standartta özellikle izin verilemez? Standartta ise, bu bir hata değildir!
Ben Hymers

8
@BenHymers Standart, standart başlıkların bildirdiklerini belirtir ve diğer ayrılmış olmayan adları bildirmelerine izin verilmez. Üstbilgi <cstddef>bildirilebilir veya bildirilmeyebilir ::size_t, bu nedenle, özel olarak <stddef.h>C kütüphanesinden bildirilmesi garanti edilen başka bir üstbilgi içermedikçe, orada olmasına veya yokluğuna güvenemezsiniz .
Potatoswatter

4
@Potatoswatter: Ah, şimdi ne demek istediğini anlıyorum! Bir cümle içinde çok fazla “izin” ile kafam karışmış olmalı. Yine de ilk yorumunuzun çok güçlü olduğunu düşünüyorum; az önce söylediğin gibi, ::size_tiçinde var <stddef.h>, yani her zaman kalifiye olmana gerek yok std::.
Ben Hymers

16

C ++ 03 "17.4.3.1.4 Türlerinden":

Standart C kütüphanesindeki her tip T için (dipnot 169), :: T ve std :: T tipleri uygulamaya ayrılmıştır ve tanımlandığında :: T, std :: T ile aynı olacaktır.

Ve dipnot 169:

Bu türler 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 ve wint_t şeklindedir.


Peki, taşınabilir kod std::Ttanımlanmış değişkenlere dayanmamalıdır?
Mankarse

5
@Mankarse: Yalnızca ilgili başlığın C sürümünü eklerseniz bunların tanımlanmasına güvenmemelisiniz . Eğer #include <stddef.h>o zaman std::size_tolabilir veya mevcut olmayabilir. Eğer varsa #include <cstddef>o zaman std::size_tmevcuttur, ancak size_tkudreti olamaz.
Dennis Zickefoose

4
@Mankarse: Oposite. Üstbilgilerin C ++ sürümleri bunları içinde tanımlamalı std::ve paragraf, üst düzey ad alanında da tanımlayabileceğini ve eğer varsa, bunları aynı std::ve üst düzey olarak tanımlaması gerektiğini söylüyor . Çoğu derleyici sadece C üstbilgisini içerir ve adları std::içeri aktarır, böylece semboller her ikisinde de tanımlanır.
Jan Hudec

4
Şahsen, hiçbir zaman <cxxxxx> başlıkları veya std::C sahilinden gelen tanımlayıcıların varyantları ile uğraşmam . <xxxxx.h>Standart C başlıkları için sadık kalıyorum - bu hiç sorun olmadı. Bu yüzden, ikinci bir düşünce kullanırdım <stddef.h>ve size_tasla std::size_t; aslında, aklıma asla geçmez std::size_t.
Michael Burr

12

std :: size_t aslında stddef.h 's size_t ' dir .

cstddef aşağıdakileri verir:

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

... önceki tanımı etkin bir şekilde std ad alanına getiriyor.


Nawaz'ın belirttiği gibi, aslında tam tersi. İçeremez <cstddef>ve almayı bekleyemezsiniz ::size_t, ancak eklerseniz <stddef.h>alırsınız std::size_t.
MSalters

4
@MSalters, takip etmiyorum. Dahil <stddef.h>sadece seni alacak ::size_t.
hifier

2
Bu, uygulamanızdaki bir hatadır.
MSalters

4
@MSalters, tam olarak takip etmiyorum. Başka türlü olmamalı mı? <cstddef> C ++ 'dan geliyor, bu yüzden std :: *' de bir şeyler tanımlamalısınız. Öte yandan, stddef.h gibi bir C başlığında sadece C türünü beklerim, yani :: size_t.
Ela782

11
@MSalters, C ++ 11'den beri doğru değil. Eğer eklerseniz, <cstddef>almak için garantilidir std::size_tve ayrıca alabilirsiniz ::size_t(ancak garanti edilmez). Eğer dahil <stddef.h>ederseniz alacağınız garanti ::size_tve ayrıca alabilirsiniz std::size_t(ancak garanti edilmez). C ++ 03'te farklıydı, ancak etkili bir şekilde uygulanamaz ve bir kusur olarak düzeltildi.
Jonathan Wakely
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.