Comme titre: size_t est-il toujours non signé, c'est-à-dire pour size_t x
, est x
toujours >= 0
?
Oui. C'est généralement défini comme quelque chose comme ce qui suit (sur les systèmes 32 bits):
typedef unsigned int size_t;
Référence:
La section standard 18.1 de C++ définit size_t
est dans <cstddef>
qui est décrit dans la norme C comme <stddef.h>
.
C La section 4.1.5 de la norme définit size_t
comme type entier non signé du résultat de l'opérateur sizeof
Selon la norme ISO C 1999 (C99), size_t
est un type entier non signé d'au moins 16 bits (voir les sections 7.17 et 7.18.3).
La norme recommande également que size_t
ne doit pas avoir un rang de conversion entier supérieur à long
si possible, c'est-à-dire cast size_t
à unsigned long
n'est pas problématique si la recommandation est suivie.
La norme ANSI C 1989 (ANSI C) ne mentionne pas une taille minimale ou un rang de conversion recommandé.
La norme ISO C++ 1998 (C++ 98) (ainsi que le projet actuel pour C++ 0x) fait référence à la norme C. L'article 18.1 se lit comme suit:
Le contenu est le même que l'en-tête de la bibliothèque C standard
<stddef.h>
[...]
Selon la section 1.2, cela signifie la bibliothèque telle que définie par la norme ISO C de 1990 (C90), y compris son premier amendement de 1995 (C95):
La bibliothèque décrite à l'article 7 de l'ISO/CEI 9899: 1990 et à l'article 7 de l'ISO/CEI 9899/AMD.1: 1995 est appelée ci-après Bibliothèque C standard.
Les parties concernant size_t
devrait être hérité d'ANSI C: Frontmatter et numérotation des sections mis à part, les normes pour C90 et ANSI C sont identiques. J'aurais besoin d'une copie de l'amendement normatif pour être sûr qu'il n'y a pas eu de changements pertinents à stddef.h
, mais j'en doute. La taille minimale semble être introduite avec stdint.h
, c'est-à-dire C99.
Veuillez également considérer la citation suivante de la section 1.2 de C++ 98:
Toutes les normes sont sujettes à révision et les parties prenantes des accords fondés sur la présente Norme internationale sont invitées à rechercher la possibilité d'appliquer les éditions les plus récentes des normes indiquées ci-dessous.
Oui, size_t est garanti d'être un type non signé.
Selon la norme, il n'est pas signé, mais je rappelle que certaines implémentations plus anciennes utilisaient un type signé pour le typedef.
À partir d'un ancien document GCC:
Il existe un problème potentiel avec le type size_t et les versions de GCC avant la version 2.4. ANSI C requiert que
size_t
toujours être un type non signé. Pour la compatibilité avec les fichiers d'en-tête des systèmes existants, GCC définitsize_t
dansstddef.h
pour être quel que soit le type du systèmesys/types.h
le définit. La plupart des systèmes Unix qui définissentsize_t
danssys/types.h
, définissez-le comme un type signé. Du code dans la bibliothèque dépend desize_t
étant un type non signé, et ne fonctionnera pas correctement s'il est signé
Je ne sais pas à quel point il serait important de se prémunir contre cela. Mon code suppose qu'il n'est pas signé.
La taille_t doit suivre la même définition que la norme C, et à plusieurs endroits dans la norme C++, cela implique que c'est natura non signé (en particulier dans les définitions des arguments du modèle d'allocateur).
Sur la norme C++, section 18.1 (ISO/IEC 14882 - Première édition 1998-01-01):
Le tableau 15 répertorie les types définis: ptrdiff_t et size_t
3 Le contenu est le même que l'en-tête de bibliothèque Standard C, avec les modifications suivantes: 4 La macro NULL est une constante de pointeur nul C++ définie par l'implémentation dans la présente Norme internationale (4.10).
La macro offsetof accepte un ensemble restreint d'arguments de type dans la présente Norme internationale. le type doit être une structure POD ou une union POD (article 9). Le résultat de l'application de la macro offsetof à un champ qui est un membre de données statique ou un membre de fonction n'est pas défini. VOIR ÉGALEMENT: paragraphe 5.3.3, Sizeof, paragraphe 5.7, Opérateurs additifs, paragraphe 12.5, Free store et paragraphe ISO C 7.1.6.
Oh, c'est tout simplement terrible:
vector<MyObject> 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];
}
Considérons maintenant le cas d'utilisation où arr est vide.