Widzę zmienne zdefiniowane w tym typie, ale nie wiem, skąd one pochodzą, ani do czego służą. Dlaczego nie użyć int lub unsigned int? (A co z innymi „podobnymi” typami? Void_t itp.).
@kjfletch: hhhmmm, to dziwne, że wyszukiwanie terminu „size_t” (tak jak wcześniej) nie zwróciło tego pytania.
Eliseo Ocampos
1
@Eliseo - Funkcja wyszukiwania Stackoverflow jest okropna. Zamiast tego użyj Google z parametrem „site: stackoverflow.com”.
Michael Burr
8
Program operacyjny zapytał konkretnie Gdzie znajdę definicję size_t? Wylądowałem tutaj, szukając tego samego. Cytowany dup nie omawia, gdzie znaleźć deklarację.
jww
9
To oczywiście nie jest to samo pytanie, co pytanie połączone. „Gdzie coś znajdę” to nie to samo, co „Jaka jest różnica między” (nawet jeśli odpowiedź na jedno jest odpowiedzią na drugą). Moje wyszukiwanie w Google „c ++ gdzie jest definicja size_t” zaprowadziło mnie prosto tutaj i pominąłbym inne pytanie, ponieważ jest inne .
stdlib.hI stddef.hheader pliki określić typ danych o nazwie size_t1 , który jest używany do reprezentowania rozmiaru obiektu. Funkcje biblioteczne, które przyjmują rozmiary, oczekują, że będą typu size_t, a operator sizeof oblicza wartość size_t.
Rzeczywisty typ size_tzależy od platformy; częstym błędem jest założenie, że size_tjest to to samo, co unsigned int, co może prowadzić do błędów w programowaniu, 2 zwłaszcza, gdy coraz bardziej rozpowszechnione są architektury 64-bitowe.
To jest dokładnie to, czego potrzebowałem, tę odpowiedź należy zaakceptować.
neodelphi
27
size_t jest typem liczby całkowitej bez znaku wyniku operatora sizeof (ISO C99 sekcja 7.17.)
sizeofOperator uzyskuje rozmiar (w bajtach) jej argumentu operacji, który może być ekspresja lub nawiasach nazwa typu. Rozmiar jest określany na podstawie typu operandu. Wynik jest liczbą całkowitą. Wartość wyniku jest zdefiniowana w ramach implementacji, a jego typ (typ liczby całkowitej bez znaku) to size_t(ISO C99 sekcja 6.5.3.4.)
@Martin - to prawda, ale myślę, że część pytania „dlaczego nie jest używany bez znaku” jest równie interesująca (lub bardziej) jak część „co to jest rozmiar_t” i nie znajdziesz tego w standardzie .
Michael Burr,
Tak, z wyjątkiem tego, że nie ma sekcji 17.17 : s. To rzadkie, nikt nie powiedział ani słowa o Void_t
Eliseo
Akceptuję tę odpowiedź, ponieważ odpowiada bezpośrednio na pytanie, ale byłoby wspaniale, gdyby była uzupełniona odpowiedzią Michaela.
Eliseo Ocampos
58
Szkoda, że twoja odpowiedź nie mówi mi, jaki plik nagłówkowy dołączyć.
Matt
6
Praktycznie size_treprezentuje liczbę bajtów, które możesz zaadresować. W większości nowoczesnych architektur przez ostatnie 10-15 lat było to 32 bity, co również było wielkością niepodpisanego int. Jednak przechodzimy do adresowania 64-bitowego, podczas gdy uintnajprawdopodobniej pozostanie na 32 bitach (jego rozmiar nie jest gwarantowany w standardzie c ++). Aby utworzyć kod, który zależy od rozmiaru pamięci przenośnej między architekturami, należy użyć pliku size_t. Na przykład rzeczy takie jak rozmiary tablic powinny zawsze używać size_t's. Jeśli spojrzysz na standardowe kontenery, ::size()zawsze zwraca a size_t.
Należy również zauważyć, że program Visual Studio ma opcję kompilacji, która może sprawdzać tego typu błędy o nazwie „Wykryj problemy z 64-bitową mobilnością”.
W ten sposób zawsze wiesz jaki jest rozmiar, ponieważ do rozmiarów dedykowany jest konkretny typ. Samo pytanie pokazuje, że może to być problem: czy to jest intczy unsigned int? Ponadto, co jest wielkością ( short, int, long, itd.)?
Ponieważ jest przypisany określony typ, nie musisz martwić się o długość lub liczbę podpisów.
size_todpowiada całkowitemu typowi danych zwróconym przez operator języka sizeofi jest zdefiniowany w <cstring>pliku nagłówkowym (między innymi) jako typ całkowity bez znaku.
W <cstring>, jest on stosowany jako typ parametru numw funkcji memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyi strxfrm, które we wszystkich przypadkach jest używany do określenia maksymalnej liczby bajtów lub znaków funkcja musi mieć wpływ.
Jest również stosowany jako typ zwracany do strcspn, strlen, strspni strxfrmdo powrotu rozmiarach i długościach.
size_t powinno być zdefiniowane w nagłówkach twojej standardowej biblioteki. Z mojego doświadczenia wynika, że zwykle jest to po prostu typedef do unsigned int. Chodzi jednak o to, że nie musi tak być. Typy, takie jak size_t, pozwalają dostawcy biblioteki standardowej na swobodę zmiany podstawowych typów danych, jeśli jest to odpowiednie dla platformy. Jeśli założysz, że size_t jest zawsze unsigned int (poprzez rzutowanie itp.), Możesz napotkać problemy w przyszłości, jeśli dostawca zmieni size_t na np. Typ 64-bitowy. Z tego powodu zakładanie czegokolwiek na temat tego lub jakiegokolwiek innego typu biblioteki jest niebezpieczne.
Nie jestem zaznajomiony z void_twyjątkiem wyniku wyszukiwania Google (nie jest to stosowane w w vmallocbibliotece przez Kiem-Phong Vo w AT & T Badań - Jestem pewien, że jest on wykorzystywany w innych bibliotekach, jak również).
Różne typy definicji xxx_t są używane do abstrakcji typu z konkretnej określonej implementacji, ponieważ konkretne typy używane do pewnych rzeczy mogą się różnić w zależności od platformy. Na przykład:
size_t wyodrębnia typ używany do przechowywania rozmiaru obiektów, ponieważ w niektórych systemach będzie to wartość 32-bitowa, aw innych może być 16-bitowa lub 64-bitowa.
Void_twyodrębnia typ wskaźnika zwracanego przez vmallocprocedury biblioteczne, ponieważ został napisany do pracy w systemach, które są starsze niż ANSI / ISO C, gdzievoid słowo kluczowe może nie istnieć. Tak przynajmniej przypuszczam.
wchar_t wyodrębnia typ używany dla szerokich znaków, ponieważ w niektórych systemach będzie to typ 16-bitowy, w innych będzie to typ 32-bitowy.
Więc jeśli napiszesz swój kod obsługi szerokich znaków, aby użyć wchar_ttypu zamiast, powiedzmy unsigned short, kod ten będzie prawdopodobnie bardziej przenośny na różne platformy.
Częściowo tego szukałem. Jak powiedziałem w komentarzu do odpowiedzi fpmurphy, byłoby wspaniale, gdyby można było ją uzupełnić tą odpowiedzią (jeśli nie masz nic przeciwko, może możesz ją edytować) :)
Eliseo Ocampos
1
W programach minimalistycznych, w których size_tdefinicja nie została załadowana „przypadkowo” w niektórych włączeniach, ale nadal potrzebuję jej w pewnym kontekście (na przykład w celu uzyskania dostępu std::vector<double>), używam tego kontekstu do wyodrębnienia odpowiedniego typu. Na przykład typedef std::vector<double>::size_type size_t.
(Otocz, namespace {...}jeśli to konieczne, aby ograniczyć zasięg.)
Jeśli chodzi o „Dlaczego nie używać int lub unsigned int?”, Po prostu dlatego, że jest to semantycznie bardziej sensowne, aby tego nie robić. Istnieje praktyczny powód, dla którego można to, powiedzmy, typedefd jako an, inta następnie uaktualnić do longpóźniejszego, oczywiście bez konieczności zmiany kodu przez nikogo, ale bardziej fundamentalnie niż to, że typ ma mieć znaczenie. Aby znacznie uprościć, zmienna typu size_tnadaje się do przechowywania rozmiarów rzeczy i służy do tego, tak jak time_tnadaje się do przechowywania wartości czasu. Sposób, w jaki są one faktycznie wdrażane, powinien być całkiem właściwy dla implementacji. W porównaniu do zwykłego wywoływania wszystkiego int, używanie znaczących nazw typów, takich jak ta, pomaga wyjaśnić znaczenie i cel programu, tak jak robi to każdy bogaty zestaw typów.
Odpowiedzi:
Z Wikipedii
Od C99 7.17.1 / 2
źródło
int
aunsigned int
typy to 32 bity, a size_t to 64 bity.Zgodnie z opisem size_t na en.cppreference.com
size_t
zdefiniowano w następujących nagłówkach:źródło
size_t
jest typem liczby całkowitej bez znaku wyniku operatora sizeof (ISO C99 sekcja 7.17.)sizeof
Operator uzyskuje rozmiar (w bajtach) jej argumentu operacji, który może być ekspresja lub nawiasach nazwa typu. Rozmiar jest określany na podstawie typu operandu. Wynik jest liczbą całkowitą. Wartość wyniku jest zdefiniowana w ramach implementacji, a jego typ (typ liczby całkowitej bez znaku) tosize_t
(ISO C99 sekcja 6.5.3.4.)źródło
Praktycznie
size_t
reprezentuje liczbę bajtów, które możesz zaadresować. W większości nowoczesnych architektur przez ostatnie 10-15 lat było to 32 bity, co również było wielkością niepodpisanego int. Jednak przechodzimy do adresowania 64-bitowego, podczas gdyuint
najprawdopodobniej pozostanie na 32 bitach (jego rozmiar nie jest gwarantowany w standardzie c ++). Aby utworzyć kod, który zależy od rozmiaru pamięci przenośnej między architekturami, należy użyć plikusize_t
. Na przykład rzeczy takie jak rozmiary tablic powinny zawsze używaćsize_t
's. Jeśli spojrzysz na standardowe kontenery,::size()
zawsze zwraca asize_t
.Należy również zauważyć, że program Visual Studio ma opcję kompilacji, która może sprawdzać tego typu błędy o nazwie „Wykryj problemy z 64-bitową mobilnością”.
źródło
W ten sposób zawsze wiesz jaki jest rozmiar, ponieważ do rozmiarów dedykowany jest konkretny typ. Samo pytanie pokazuje, że może to być problem: czy to jest
int
czyunsigned int
? Ponadto, co jest wielkością (short
,int
,long
, itd.)?Ponieważ jest przypisany określony typ, nie musisz martwić się o długość lub liczbę podpisów.
Rzeczywistą definicję można znaleźć w C ++ Reference Library , która mówi:
źródło
size_t powinno być zdefiniowane w nagłówkach twojej standardowej biblioteki. Z mojego doświadczenia wynika, że zwykle jest to po prostu typedef do unsigned int. Chodzi jednak o to, że nie musi tak być. Typy, takie jak size_t, pozwalają dostawcy biblioteki standardowej na swobodę zmiany podstawowych typów danych, jeśli jest to odpowiednie dla platformy. Jeśli założysz, że size_t jest zawsze unsigned int (poprzez rzutowanie itp.), Możesz napotkać problemy w przyszłości, jeśli dostawca zmieni size_t na np. Typ 64-bitowy. Z tego powodu zakładanie czegokolwiek na temat tego lub jakiegokolwiek innego typu biblioteki jest niebezpieczne.
źródło
Nie jestem zaznajomiony z
void_t
wyjątkiem wyniku wyszukiwania Google (nie jest to stosowane w wvmalloc
bibliotece przez Kiem-Phong Vo w AT & T Badań - Jestem pewien, że jest on wykorzystywany w innych bibliotekach, jak również).Różne typy definicji xxx_t są używane do abstrakcji typu z konkretnej określonej implementacji, ponieważ konkretne typy używane do pewnych rzeczy mogą się różnić w zależności od platformy. Na przykład:
Void_t
wyodrębnia typ wskaźnika zwracanego przezvmalloc
procedury biblioteczne, ponieważ został napisany do pracy w systemach, które są starsze niż ANSI / ISO C, gdzievoid
słowo kluczowe może nie istnieć. Tak przynajmniej przypuszczam.wchar_t
wyodrębnia typ używany dla szerokich znaków, ponieważ w niektórych systemach będzie to typ 16-bitowy, w innych będzie to typ 32-bitowy.Więc jeśli napiszesz swój kod obsługi szerokich znaków, aby użyć
wchar_t
typu zamiast, powiedzmyunsigned short
, kod ten będzie prawdopodobnie bardziej przenośny na różne platformy.źródło
W programach minimalistycznych, w których
size_t
definicja nie została załadowana „przypadkowo” w niektórych włączeniach, ale nadal potrzebuję jej w pewnym kontekście (na przykład w celu uzyskania dostępustd::vector<double>
), używam tego kontekstu do wyodrębnienia odpowiedniego typu. Na przykładtypedef std::vector<double>::size_type size_t
.(Otocz,
namespace {...}
jeśli to konieczne, aby ograniczyć zasięg.)źródło
Jeśli chodzi o „Dlaczego nie używać int lub unsigned int?”, Po prostu dlatego, że jest to semantycznie bardziej sensowne, aby tego nie robić. Istnieje praktyczny powód, dla którego można to, powiedzmy,
typedef
d jako an,int
a następnie uaktualnić dolong
późniejszego, oczywiście bez konieczności zmiany kodu przez nikogo, ale bardziej fundamentalnie niż to, że typ ma mieć znaczenie. Aby znacznie uprościć, zmienna typusize_t
nadaje się do przechowywania rozmiarów rzeczy i służy do tego, tak jaktime_t
nadaje się do przechowywania wartości czasu. Sposób, w jaki są one faktycznie wdrażane, powinien być całkiem właściwy dla implementacji. W porównaniu do zwykłego wywoływania wszystkiegoint
, używanie znaczących nazw typów, takich jak ta, pomaga wyjaśnić znaczenie i cel programu, tak jak robi to każdy bogaty zestaw typów.źródło