è size_t sempre senza segno?

Come titolo: è size_t sempre senza segno, cioè per size_t x , è x sempre >= 0 ?

Di solito è definito come qualcosa di simile (su sistemi a 32 bit):

 typedef unsigned int size_t; 

Riferimento:

C ++ Standard Section 18.1 definisce size_t è in che è descritto in C Standard come .
C La sezione 4.1.5 definisce size_t come un tipo integrale senza segno del risultato dell’operatore sizeof

In base allo standard ISO C del 1999 (C99), size_t è un tipo intero senza segno di almeno 16 bit (vedere le sezioni 7.17 e 7.18.3).

Lo standard raccomanda inoltre che size_t non dovrebbe avere un rank di conversione intero maggiore di long se ansible, ad esempio il cast size_t in unsigned long è problematico se viene seguito il consiglio.

Lo standard ANSI C del 1989 (ANSI C) non menziona una dimensione minima o un rango di conversione raccomandato.

Lo standard ISO C ++ del 1998 (C ++ 98) (così come la bozza corrente per C ++ 0x) si riferisce allo standard C. La sezione 18.1 recita:

I contenuti sono gli stessi dell’intestazione della libreria standard C […]

Secondo la sezione 1.2, si intende la biblioteca come definita dalla norma ISO C del 1990 (C90), compreso il primo emendamento del 1995 (C95):

La libreria descritta nella clausola 7 della ISO / IEC 9899: 1990 e la clausola 7 della ISO / IEC 9899 / Amd.1: 1995 è in appresso denominata Libreria standard C.

Le parti relative a size_t devono essere ereditate da ANSI C: Frontmatter e la numerazione delle sezioni a parte, gli standard per C90 e ANSI C sono identici. Avrei bisogno di una copia dell’emendamento normativo per essere sicuro che non ci fossero modifiche rilevanti a stddef.h , ma ne dubito. La dimensione minima sembra essere introdotta con stdint.h , cioè C99.

Si prega di considerare anche la seguente citazione dalla sezione 1.2 di C ++ 98:

Tutti gli standard sono soggetti a revisione e le parti agli accordi basati su questo standard internazionale sono incoraggiati a valutare la possibilità di applicare le edizioni più recenti degli standard indicati di seguito.

Sì, size_t è garantito come un tipo senza segno.

Secondo lo standard non è firmato, tuttavia ricordo che alcune implementazioni precedenti usavano un tipo firmato per il typedef.

Da un vecchio documento GCC:

Esiste un potenziale problema con il tipo size_t e le versioni di GCC precedenti alla versione 2.4. ANSI C richiede che size_t sempre un tipo senza segno. Per la compatibilità con i file di intestazione dei sistemi esistenti, GCC definisce size_t in stddef.h come qualunque sia il tipo di sistema sys/types.h . La maggior parte dei sistemi Unix che definiscono size_t in sys/types.h , lo definiscono come un tipo firmato. Alcuni codici nella libreria dipendono dal fatto che size_t è un tipo non firmato e non funzionerà correttamente se è firmato

Non sono sicuro di quanto sia importante proteggerci da questo. Il mio codice presuppone che non sia firmato.

La dimensione_t dovrebbe seguire la stessa definizione dello standard C, e in diversi punti nello standard C ++ implica che è unsigned natura (in particolare nelle definizioni degli argomenti del template allocator).

Nello standard C ++, sezione 18.1 (ISO / IEC 14882 – Prima edizione 1998-01-01):

La tabella 15 elenca i tipi definiti: ptrdiff_t e size_t

3 I contenuti sono gli stessi dell’intestazione della libreria C standard, con le seguenti modifiche: 4 La macro NULL è una costante di puntatore nullo C ++ definita dall’implementazione in questo standard internazionale (4.10).

La macrooffsetof accetta un insieme limitato di argomenti di tipo in questo standard internazionale. il tipo deve essere una struttura POD o un’unione POD (clausola 9). Il risultato dell’applicazione dell’offset della macro a un campo che è un membro dati statico o un membro di funzione non è definito. VEDERE ANCHE: subclause 5.3.3, Sizeof, subclause 5.7, Operatori additivi, subclause 12.5, Free store e subclaus ISO C 7.1.6.

Oh, questo è semplicemente terribile:

 vector arr; Fill(arr); size_t size = arr.size(); for(size_t i = 1; i < size - 1; ++i) { auto obj = arr[i]; auto next = arr[i+1]; } 

Ora contempla il caso d'uso in cui arr è vuoto.