Differenza tra size_t e std :: size_t


139

Quali sono le differenze tra size_te std::size_tin termini di dove vengono dichiarate, quando dovrebbero essere utilizzate e qualsiasi altra caratteristica di differenziazione?


Sarei interessato a sapere se la specifica C ++ collega std :: size_t al tipo C size_t.
Doug T.,

Vedi domanda simile: link
Mankarse

Risposte:


88

C size_te C ++ std::size_tsono entrambi uguali.

In C, è definito in <stddef.h>e in C ++, è definito nei <cstddef>cui contenuti sono gli stessi dell'intestazione C (vedere la citazione seguente). Sua definita senza segno tipo integer del risultato del sizeof operatore.

C Standard dice in §17.7 / 2,

size_t che è il tipo intero senza segno del risultato della sizeof operatore

E lo standard C ++ dice (sull'intestazione cstddef) in §18.1 / 3,

I contenuti sono gli stessi dell'intestazione della libreria C standard, con le seguenti modifiche .

Quindi sì, entrambi sono uguali; l'unica differenza è che C ++ definisce size_tnello stdspazio dei nomi.

Si noti inoltre che la riga sopra dice anche "con le seguenti modifiche" a cui non fa riferimento size_t. Si riferisce piuttosto alle nuove aggiunte (principalmente) fatte da C ++ nel linguaggio (non presente in C) che sono anche definite nella stessa intestazione.


Wikipedia ha ottime informazioni su intervallo e dimensioni di archiviazione di size_t:

Intervallo e dimensioni di archiviazione di size_t

Il tipo effettivo di size_t dipende dalla piattaforma ; un errore comune è supporre che size_t sia uguale a unsigned int, il che può portare ad errori di programmazione, [3] [4] quando si passa da un'architettura a 32 a 64 bit, ad esempio.

Secondo lo standard ISO C del 1999 (C99), size_t è un tipo intero senza segno di almeno 16 bit.

E il resto è possibile leggere da questa pagina su Wikipedia.


Questo porta ad un altro Q, se STL importa già size_t attraverso C (cstddef) perché ha di nuovo una sua versione?
Risparmia il

43
@Als: A rigor di termini, è un errore dire size_tsenza using namespace std;o using std::size_t;. Tuttavia, la maggior parte dei compilatori lo consente e lo Standard consente espressamente loro di consentirlo (§D.5 / 3).
Potatoswatter,

9
@Potatoswatter: Sicuramente non può essere sia un errore che specificamente consentito nello standard? Se è nello standard, non è un errore!
Ben Hymers,

8
@BenHymers Lo standard specifica ciò che dichiarano le intestazioni standard e non sono autorizzati a dichiarare altri nomi non riservati. L'intestazione <cstddef>può o non può essere dichiarata ::size_t, quindi non puoi fare affidamento sul fatto che sia lì o che sia assente, a meno che non includa specificamente <stddef.h>o un'altra intestazione dalla libreria C che è garantita per dichiararla.
Potatoswatter,

4
@Potatoswatter: Ah, capisco cosa intendi adesso! Devo essermi confuso da troppi "permetti" in una frase. Penso comunque che il tuo primo commento sia troppo forte; come hai appena detto, ::size_tè presente ad esempio in <stddef.h>, quindi non è sempre necessario qualificarlo std::.
Ben Hymers,

16

Da C ++ 03 "Tipi 17.4.3.1.4":

Per ogni tipo T dalla libreria Standard C (nota 169), i tipi :: T e std :: T sono riservati all'implementazione e, quando definiti, :: T devono essere identici a std :: T.

E nota 169:

Questi tipi sono 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 e wint_t.


Quindi il codice portatile non dovrebbe fare affidamento sulle std::Tvarianti che vengono definite?
Mankarse,

5
@Mankarse: non dovresti fare affidamento sulla loro definizione se includi solo la versione C dell'intestazione corrispondente. Se #include <stddef.h>quindi std::size_tpotresti o non essere disponibile. Se sei #include <cstddef>quindi std::size_tdisponibile, ma size_tpotrebbe non esserlo.
Dennis Zickefoose,

4
@Mankarse: l'opposto. Le versioni C ++ delle intestazioni devono definirle in std::e il paragrafo dice che può anche definirle nello spazio dei nomi di livello superiore e, in caso affermativo, deve definirle in modo identico std::e di livello superiore. La maggior parte dei compilatori include solo l'intestazione C e importa i nomi std::, quindi i simboli finiscono per essere definiti in entrambi.
Jan Hudec,

4
Personalmente, non mi preoccupo mai delle intestazioni <cxxxxx> o delle std::varianti di identificatori che provengono dalla riva C. Rispetto alle <xxxxx.h>intestazioni C standard: non è mai stato un problema. Così, mi piacerebbe utilizzare <stddef.h>e size_tsenza mai dare un secondo pensiero a std::size_t; in realtà, non mi viene mai in mente che esiste (o potrebbe esserci) a std::size_t.
Michael Burr,

12

std :: size_t è infatti stddef.h 's size_t .

cstddef fornisce quanto segue:

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

... portando efficacemente la definizione precedente nello spazio dei nomi std.


Come sottolinea Nawaz, in realtà è il contrario. Non puoi includere <cstddef>e aspettarti di ottenere ::size_t, ma se includi <stddef.h>otterrai std::size_t.
MSalters,

4
@MSalters, non seguo. Compreso <stddef.h>ti prenderà solo ::size_t.
hifier

2
Questo è un bug nella tua implementazione, quindi.
MSalters

4
@MSalters, non lo seguo del tutto. Non dovrebbe essere il contrario? <cstddef> proviene da C ++, quindi dovrebbe definire le cose in std :: *? D'altra parte, in un'intestazione C, come stddef.h, mi aspetterei solo il tipo C, cioè :: size_t.
Ela782

11
@MSalters, poiché C ++ 11 non è preciso. Se includi <cstddef>hai la garanzia di ottenere std::size_te potresti anche ottenere ::size_t(ma non è garantito). Se includi <stddef.h>hai la garanzia di ottenere ::size_te potresti anche ottenere std::size_t(ma non è garantito). Era diverso in C ++ 03 ma era effettivamente inattuabile e risolto come difetto.
Jonathan Wakely,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.