Gdzie znajdę definicję size_t?


123

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 .
Dan Nissenbaum

Odpowiedzi:


122

Z Wikipedii

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.

Od C99 7.17.1 / 2

W standardowym nagłówku zdefiniowano następujące typy i makra stddef.h

<snip>

size_t

który jest typem liczby całkowitej bez znaku wyniku operatora sizeof


2
Na przykład w Win64, inta unsigned inttypy to 32 bity, a size_t to 64 bity.
Michael Burr

7
Proszę zapoznać się ze standardem ISO C (99) (z którego standard C ++ obejmuje) sekcje 7.17 i 7.18.3
Martin York,

3
@LokiAstari może po prostu edytujesz odpowiedź, skoro wiesz, gdzie jest ona zapisana w standardzie?
Hi-Angel

Więc gdzie jest odpowiedź C ++?
Lothar

@Lothar Myślę, że jedyną różnicą jest to, że size_t może być słowem kluczowym, a poza tym ma to samo znaczenie.
Paul Stelian,

30

Zgodnie z opisem size_t na en.cppreference.com size_t zdefiniowano w następujących nagłówkach:

std::size_t

...    

Defined in header <cstddef>         
Defined in header <cstdio>      
Defined in header <cstring>         
Defined in header <ctime>       
Defined in header <cwchar>

2
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.)


Najlepsza odpowiedź, ponieważ cytuje standard.
Martin York,

1
@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ą”.


2

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.

Rzeczywistą definicję można znaleźć w C ++ Reference Library , która mówi:

Typ: size_t(typ całkowity bez znaku)

Nagłówek: <cstring>

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.


2

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.


1

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.)


1

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.