web-dev-qa-db-fra.com

size_t est-il toujours non signé?

Comme titre: size_t est-il toujours non signé, c'est-à-dire pour size_t x, est x toujours >= 0?

57
peterchen

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

48
Mehrdad Afshari

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.

51
Christoph

Oui, size_t est garanti d'être un type non signé.

14
nos

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éfinit size_t dans stddef.h pour être quel que soit le type du système sys/types.h le définit. La plupart des systèmes Unix qui définissent size_t dans sys/types.h, définissez-le comme un type signé. Du code dans la bibliothèque dépend de size_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é.

5
Michael Burr

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.

2
njsf

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.