Dove trovo la definizione di size_t?


123

Vedo variabili definite con questo tipo ma non so da dove provenga, né qual è il suo scopo. Perché non utilizzare int o unsigned int? (E gli altri tipi "simili"? Void_t, ecc.).



@kjfletch: hhhmmm, è strano che la ricerca del termine "size_t" (come ho fatto in precedenza) non abbia restituito quella domanda.
Eliseo Ocampos

1
@Eliseo - La funzione di ricerca di Stackoverflow è orribile. Utilizza invece Google con un parametro "site: stackoverflow.com".
Michael Burr

8
L'OP ha chiesto specificatamente Dove trovo la definizione di size_t? Sono atterrato qui cercando la stessa cosa. Il citato dup non discute dove trovare la dichiarazione.
jww

9
Questa domanda ovviamente non è la stessa domanda di quella collegata. "Dove trovo qualcosa" non è la stessa cosa di "Qual è la differenza tra" (anche se la risposta a uno fornisce la risposta all'altro). La mia ricerca su Google per "c ++ dove è la definizione di size_t" mi ha portato direttamente qui, e mi sarei perso l'altra domanda, perché è diversa .
Dan Nissenbaum

Risposte:


122

Da Wikipedia

I file di intestazione stdlib.he stddef.hdefiniscono un tipo di dati chiamato size_t1 che viene utilizzato per rappresentare la dimensione di un oggetto. Le funzioni di libreria che accettano dimensioni si aspettano che siano di tipo size_te l'operatore sizeof restituisce size_t.

Il tipo effettivo di size_tdipende dalla piattaforma; un errore comune è presumere che size_tsia uguale a unsigned int, che può portare a errori di programmazione, 2 in particolare quando le architetture a 64 bit diventano più diffuse.

Da C99 7.17.1 / 2

I seguenti tipi e macro sono definiti nell'intestazione standard stddef.h

<Snip>

size_t

che è il tipo intero senza segno del risultato dell'operatore sizeof


2
Ad esempio, su Win64, inte i unsigned inttipi sono 32 bit, mentre size_t è 64 bit.
Michael Burr

7
Fare riferimento allo standard ISO C (99) (da cui lo standard C ++ include) sezioni 7.17 e 7.18.3
Martin York

3
@LokiAstari perché non modifichi la risposta dato che sai dove è scritta nello standard?
Hi-Angel

Allora dov'è la risposta in C ++?
Lothar

@ Lothar Penso che l'unica differenza sia che size_t potrebbe essere una parola chiave, e altrimenti ha lo stesso significato.
Paul Stelian

30

Secondo size_t, la descrizione su en.cppreference.com size_t è definita nelle seguenti intestazioni:

std::size_t

...    

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

2
Questo è esattamente ciò di cui avevo bisogno, questa risposta dovrebbe essere votata.
neodelphi

27

size_t è il tipo intero senza segno del risultato dell'operatore sizeof (ISO C99 sezione 7.17.)

L' sizeofoperatore restituisce la dimensione (in byte) del suo operando, che può essere un'espressione o il nome tra parentesi di un tipo. La dimensione è determinata dal tipo di operando. Il risultato è un numero intero. Il valore del risultato è definito dall'implementazione e il suo tipo (un tipo intero senza segno) è size_t(ISO C99 Sezione 6.5.3.4.)


La migliore risposta in quanto cita lo standard.
Martin York

1
@ Martin - abbastanza vero, ma penso che la parte della domanda "perché non è usato int senza segno" sia interessante (o più) quanto la parte "cosa è size_t" e non la troverai nello standard .
Michael Burr

Sì, tranne che non esiste una "Sezione 17.17 ": p. È raro, nessuno ha detto una parola su Void_t
Eliseo Ocampos

Accetto questa risposta in quanto risponde direttamente alla domanda, ma sarebbe fantastico se fosse complimentata con la risposta di Michael.
Eliseo Ocampos

58
Peccato che la tua risposta non mi dica quale file di intestazione includere.
Matt

6

In pratica size_trappresenta il numero di byte che puoi indirizzare. Sulla maggior parte delle architetture moderne negli ultimi 10-15 anni sono stati 32 bit che hanno anche avuto le dimensioni di un int senza segno. Tuttavia ci stiamo spostando verso l'indirizzamento a 64 bit mentre uintmolto probabilmente rimarrà a 32 bit (la sua dimensione non è garantita nello standard c ++). Per rendere il tuo codice che dipende dalla dimensione della memoria portabile attraverso le architetture dovresti usare un file size_t. Ad esempio cose come le dimensioni degli array dovrebbero sempre usare size_t's. Se guardi i contenitori standard ::size()restituisce sempre un file size_t.

Si noti inoltre che Visual Studio ha un'opzione di compilazione che può verificare questi tipi di errori denominati "Rileva problemi di portabilità a 64 bit".


2

In questo modo sai sempre qual è la taglia, perché un tipo specifico è dedicato alle taglie. La stessa domanda mostra che può essere un problema: è un into uno unsigned int? Inoltre, qual è la grandezza ( short, int,long , etc.)?

Poiché è stato assegnato un tipo specifico, non devi preoccuparti della lunghezza o della firma.

La definizione effettiva può essere trovata nella libreria di riferimento C ++ , che dice:

Genere: size_t (tipo integrale senza segno)

Intestazione: <cstring>

size_tcorrisponde al tipo di dati integrale restituito dall'operatore del linguaggio sizeofed è definito nel file<cstring> file di intestazione (tra gli altri) come tipo integrale senza segno.

In <cstring>, è usato come il tipo di parametro numnelle funzioni memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyestrxfrm , che in ogni caso è utilizzato per specificare il numero massimo di byte o caratteri la funzione deve incidere.

È anche usato come tipo cambio strcspn, strlen, strspne strxfrmper le dimensioni e lunghezze ritorno.


2

size_t dovrebbe essere definito nelle intestazioni della libreria standard. Nella mia esperienza, di solito è semplicemente un typedef a unsigned int. Il punto, però, è che non deve essere così. Tipi come size_t consentono al fornitore di librerie standard la libertà di modificare i propri tipi di dati sottostanti, se appropriato per la piattaforma. Se presumi che size_t sia sempre unsigned int (tramite casting, ecc.), Potresti incorrere in problemi in futuro se il tuo fornitore cambia size_t per essere, ad esempio, un tipo a 64 bit. È pericoloso presumere qualcosa su questo o qualsiasi altro tipo di libreria per questo motivo.


1

Non ho familiarità con void_tse non come risultato di una ricerca su Google (è utilizzato in una vmalloclibreria da Kiem-Phong Vo presso AT&T Research - sono sicuro che sia usato anche in altre biblioteche).

I vari typedef xxx_t sono usati per astrarre un tipo da una particolare implementazione definita, poiché i tipi concreti usati per certe cose potrebbero differire da una piattaforma all'altra. Per esempio:

  • size_t astrae il tipo utilizzato per contenere la dimensione degli oggetti perché su alcuni sistemi questo sarà un valore a 32 bit, su altri potrebbe essere a 16 bit o 64 bit.
  • Void_tastrae il tipo di puntatore restituito dalle vmallocroutine della libreria perché è stato scritto per funzionare su sistemi che precedono ANSI / ISO C dove ilvoid parola chiave potrebbe non esistere. Almeno questo è quello che immagino.
  • wchar_t astrae il tipo usato per i caratteri larghi poiché su alcuni sistemi sarà un tipo a 16 bit, su altri sarà un tipo a 32 bit.

Quindi, se scrivi il tuo codice per la gestione dei caratteri per usare il wchar_ttipo invece di, diciamo unsigned short, quel codice sarà presumibilmente più portabile su varie piattaforme.


Questo è quello che stavo cercando, in parte. Come ho detto in un commento nella risposta di fpmurphy, sarebbe fantastico che possa essere integrato con questa risposta (se non ti dispiace, forse puoi modificarlo) :)
Eliseo Ocampos

1

Nei programmi minimalisti in cui una size_tdefinizione non è stata caricata "per caso" in alcuni include ma ne ho ancora bisogno in qualche contesto (ad esempio per accedere std::vector<double>), quindi utilizzo quel contesto per estrarre il tipo corretto. Per esempiotypedef std::vector<double>::size_type size_t .

(Circondare con namespace {...}se necessario per limitare l'ambito.)


1

Quanto a "Perché non utilizzare int o unsigned int?", Semplicemente perché semanticamente è più significativo non farlo. C'è la ragione pratica per cui può essere, diciamo, typedefd come un inte poi aggiornato a un longsecondo, senza che nessuno debba cambiare il proprio codice, ovviamente, ma più fondamentalmente di che un tipo dovrebbe essere significativo. Per semplificare enormemente, una variabile di tipo size_tè adatta e utilizzata per contenere le dimensioni delle cose, proprio come time_tè adatta per contenere valori temporali. Il modo in cui questi vengono effettivamente implementati dovrebbe essere abbastanza correttamente compito dell'implementazione. Rispetto alla semplice chiamata di tutto int, l'uso di nomi di tipo significativi come questo aiuta a chiarire il significato e l'intento del tuo programma, proprio come fa qualsiasi ricco insieme di tipi.

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.