W C jest zdefiniowany w <stddef.h>C ++ iw C ++, jego <cstddef>zawartość jest taka sama jak nagłówek C (zobacz cytat poniżej). Jest określona jako unsigned całkowitą w związku z sizeof operatora.
C Standard mówi w §17.7 / 2,
size_t który jest unsigned całkowitą od wyniku tego sizeof operatora
A C ++ Standard mówi (o cstddefnagłówku) w §18.1 / 3,
Zawartość jest taka sama, jak nagłówek standardowej biblioteki C, z następującymi zmianami .
Więc tak, oba są takie same; Jedyną różnicą jest to, który definiuje c ++ size_tw stdprzestrzeni nazw.
Proszę również zauważyć, że powyższa linia mówi również „z następującymi zmianami”, co nie dotyczy size_t. Odnosi się raczej do nowych dodatków (głównie) wprowadzonych przez C ++ do języka (nieobecnych w C), które również są zdefiniowane w tym samym nagłówku.
Wikipedia ma bardzo dobre informacje na temat zakresu i rozmiaru magazynu size_t:
Zakres i wielkość składowania size_t
Rzeczywisty typ size_t jest
zależne od platformy ; wspólny błąd
jest założenie size_t jest taka sama jak unsigned int, co może prowadzić do błędów oprogramowania, [3], [4], podczas przemieszczania się z 32 do 64 bitów architektury, na przykład.
Zgodnie z normą ISO C (C99) z 1999 r., Size_t jest liczbą całkowitą bez znaku o długości co najmniej 16 bitów.
A resztę możesz przeczytać na tej stronie w Wikipedii.
To prowadzi do kolejnego pytania: Jeśli STL już importuje size_t do C (cstddef), dlaczego ma swoją własną inną wersję?
Alok Save
43
@Als: Ściśle mówiąc, błędem jest mówić size_tbez using namespace std;lub using std::size_t;. Jednak większość kompilatorów na to zezwala, a Standard wyraźnie zezwala im na to (§D.5 / 3).
Potatoswatter
9
@Potatoswatter: Z pewnością nie może to być zarówno błąd, jak i wyraźnie dozwolone w standardzie? Jeśli jest w standardzie, nie jest to błąd!
Ben Hymers,
8
@BenHymers Standard określa, co deklarują standardowe nagłówki, i nie mogą one deklarować żadnych innych niezastrzeżonych nazw. Nagłówek <cstddef>może ::size_t, ale nie musi, deklarować , więc nie można polegać na tym, że jest obecny lub nieobecny, chyba że wyraźnie zawiera <stddef.h>lub inny nagłówek z biblioteki C, która gwarantuje, że go zadeklaruje.
Potatoswatter
4
@Potatoswatter: Ach, teraz rozumiem, co masz na myśli! Musiałem być zdezorientowany przez zbyt wiele „przyzwoleń” w jednym zdaniu. Nadal uważam, że twój pierwszy komentarz jest jednak zbyt mocny; jak właśnie powiedziałeś, ::size_tjest obecny np. w <stddef.h>, więc nie zawsze musisz go kwalifikować std::.
Ben Hymers,
16
Z C ++ 03 „17.4.3.1.4 Typy”:
Dla każdego typu T z biblioteki Standard C (przypis 169) typy :: T i std :: T są zarezerwowane dla implementacji, a po zdefiniowaniu :: T powinny być identyczne z std :: T.
I przypis 169:
Te typy to 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 i wint_t.
Zatem przenośny kod nie powinien polegać na std::Tdefiniowanych wariantach?
Mankarse
5
@Mankarse: Nie powinieneś polegać na ich zdefiniowaniu, jeśli dołączysz tylko wersję C odpowiedniego nagłówka. Jeśli #include <stddef.h>wtedy możesz std::size_tlub nie być dostępny. Jeśli #include <cstddef>wtedy jesteś std::size_tdostępny, ale size_tmoże nie być.
Dennis Zickefoose
4
@Mankarse: Naprzeciwko. Wersje nagłówków w C ++ muszą je zdefiniować w, std::a akapit mówi, że może również definiować je w przestrzeni nazw najwyższego poziomu, a jeśli tak, musi zdefiniować je identycznie na std::najwyższym poziomie. Większość kompilatorów po prostu dołącza nagłówek C i importuje nazwy do std::, więc symbole są zdefiniowane w obu.
Jan Hudec
4
Osobiście nigdy nie zawracam sobie głowy nagłówkami <cxxxxx> ani std::wariantami identyfikatorów, które pochodzą z brzegu C. Trzymam <xxxxx.h>się standardowych nagłówków C - to nigdy nie był problem. Tak, będę używać <stddef.h>i size_tnigdy nie dać namysłu do std::size_t; w rzeczywistości nigdy nie przychodzi mi do głowy, że istnieje (lub może być) a std::size_t.
Michael Burr
12
std :: size_t jest w rzeczywistości stddef.h „s size_t .
Jak podkreśla Nawaz, w rzeczywistości jest odwrotnie. Nie możesz uwzględnić <cstddef>i oczekiwać, że otrzymasz ::size_t, ale jeśli to <stddef.h>zrobisz, dostaniesz std::size_t.
MSalters
4
@MSalters, nie śledzę. Włączenie <stddef.h>tylko cię dostanie ::size_t.
hifier
2
To jest więc błąd w twojej implementacji.
MSalters
4
@MSalters, nie całkiem śledzę. Czy nie powinno być odwrotnie? <cstddef> pochodzi z C ++, więc powinien definiować zawartość w std :: *? Z drugiej strony, w nagłówku C, jak stddef.h, spodziewałbym się tylko typu C, czyli :: size_t.
Ela782
11
@MSalters, ponieważ C ++ 11 to nie jest dokładne. Jeśli dołączysz, <cstddef>masz gwarancję otrzymania std::size_ti możesz również otrzymać ::size_t(ale nie jest to gwarantowane). Jeśli dołączysz <stddef.h>, masz gwarancję, że otrzymasz ::size_ti możesz również dostać std::size_t(ale nie jest to gwarantowane). W C ++ 03 było inaczej, ale faktycznie było to niemożliwe do zaimplementowania i naprawione jako usterka.
Odpowiedzi:
C
size_t
i C ++std::size_t
są takie same.W C jest zdefiniowany w
<stddef.h>
C ++ iw C ++, jego<cstddef>
zawartość jest taka sama jak nagłówek C (zobacz cytat poniżej). Jest określona jako unsigned całkowitą w związku z sizeof operatora.C Standard mówi w §17.7 / 2,
A C ++ Standard mówi (o
cstddef
nagłówku) w §18.1 / 3,Więc tak, oba są takie same; Jedyną różnicą jest to, który definiuje c ++
size_t
wstd
przestrzeni nazw.Proszę również zauważyć, że powyższa linia mówi również „z następującymi zmianami”, co nie dotyczy
size_t
. Odnosi się raczej do nowych dodatków (głównie) wprowadzonych przez C ++ do języka (nieobecnych w C), które również są zdefiniowane w tym samym nagłówku.Wikipedia ma bardzo dobre informacje na temat zakresu i rozmiaru magazynu size_t:
A resztę możesz przeczytać na tej stronie w Wikipedii.
źródło
size_t
bezusing namespace std;
lubusing std::size_t;
. Jednak większość kompilatorów na to zezwala, a Standard wyraźnie zezwala im na to (§D.5 / 3).<cstddef>
może::size_t
, ale nie musi, deklarować , więc nie można polegać na tym, że jest obecny lub nieobecny, chyba że wyraźnie zawiera<stddef.h>
lub inny nagłówek z biblioteki C, która gwarantuje, że go zadeklaruje.::size_t
jest obecny np. w<stddef.h>
, więc nie zawsze musisz go kwalifikowaćstd::
.Z C ++ 03 „17.4.3.1.4 Typy”:
I przypis 169:
źródło
std::T
definiowanych wariantach?#include <stddef.h>
wtedy możeszstd::size_t
lub nie być dostępny. Jeśli#include <cstddef>
wtedy jesteśstd::size_t
dostępny, alesize_t
może nie być.std::
a akapit mówi, że może również definiować je w przestrzeni nazw najwyższego poziomu, a jeśli tak, musi zdefiniować je identycznie nastd::
najwyższym poziomie. Większość kompilatorów po prostu dołącza nagłówek C i importuje nazwy dostd::
, więc symbole są zdefiniowane w obu.std::
wariantami identyfikatorów, które pochodzą z brzegu C. Trzymam<xxxxx.h>
się standardowych nagłówków C - to nigdy nie był problem. Tak, będę używać<stddef.h>
isize_t
nigdy nie dać namysłu dostd::size_t
; w rzeczywistości nigdy nie przychodzi mi do głowy, że istnieje (lub może być) astd::size_t
.std :: size_t jest w rzeczywistości stddef.h „s size_t .
cstddef daje następujące informacje:
... skutecznie przenosi poprzednią definicję do przestrzeni nazw standardowej.
źródło
<cstddef>
i oczekiwać, że otrzymasz::size_t
, ale jeśli to<stddef.h>
zrobisz, dostanieszstd::size_t
.<stddef.h>
tylko cię dostanie::size_t
.<cstddef>
masz gwarancję otrzymaniastd::size_t
i możesz również otrzymać::size_t
(ale nie jest to gwarantowane). Jeśli dołączysz<stddef.h>
, masz gwarancję, że otrzymasz::size_t
i możesz również dostaćstd::size_t
(ale nie jest to gwarantowane). W C ++ 03 było inaczej, ale faktycznie było to niemożliwe do zaimplementowania i naprawione jako usterka.