Où puis-je trouver la définition de size_t?

Je vois des variables définies avec ce type mais je ne sais pas d’où cela vient, ni quel est son objective. Pourquoi ne pas utiliser int ou unsigned int? (Qu’en est-il des autres types “similaires”? Void_t, etc.).

De Wikipedia

Les fichiers d’en-tête stdlib.h et stddef.h définissent un type de données appelé size_t 1, utilisé pour représenter la taille d’un object. Les fonctions de bibliothèque qui prennent des tailles s’attendent à ce qu’elles soient de type size_t et l’opérateur sizeof à size_t .

Le type réel de size_t dépend de la plate-forme; une erreur courante est de supposer que size_t est identique à unsigned int, ce qui peut entraîner des erreurs de programmation 2, en particulier lorsque les architectures 64 bits deviennent plus répandues.

À partir de C99 7.17.1 / 2

Les types et macros suivants sont définis dans l’en-tête standard stddef.h

size_t

qui est le type entier non signé du résultat de l’opérateur sizeof

size_t est le type entier non signé du résultat de l’opérateur sizeof (ISO C99 paragraphe 7.17.)

L’opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d’un type. La taille est déterminée à partir du type de l’opérande. Le résultat est un entier. La valeur du résultat est définie par l’implémentation et son type (un type d’entier non signé) est size_t (ISO C99 Section 6.5.3.4.)

Selon la description size_t sur en.cppreference.com size_t est défini dans les en-têtes suivants:

 std::size_t ... Defined in header  Defined in header  Defined in header  Defined in header  Defined in header  

En pratique, size_t représente le nombre d’octets que vous pouvez adresser. Sur la plupart des architectures modernes des 10-15 dernières années, 32 bits ont également été de la taille d’un int non signé. Cependant, nous passons à l’adressage 64 bits alors que l’ uint restra probablement à 32 bits (sa taille n’est pas garantie dans le standard c ++). Pour rendre votre code dépendant de la taille de la mémoire portable entre les architectures, vous devez utiliser une size_t . Par exemple, les choses comme la taille des tableaux doivent toujours utiliser les size_t . Si vous regardez les conteneurs standard, la ::size() renvoie toujours une size_t .

Notez également que Visual Studio dispose d’une option de compilation permettant de vérifier ces types d’erreurs appelés “Détecter les problèmes de portabilité 64 bits”.

De cette façon, vous savez toujours quelle est la taille, car un type spécifique est dédié aux tailles. La propre question montre que cela peut être un problème: est-ce un int ou un unsigned int ? De plus, quelle est la magnitude ( short , int , long , etc.)?

Comme il y a un type spécifique assigné, vous n’avez pas à vous soucier de la longueur ou de la signature.

La définition actuelle se trouve dans la bibliothèque de référence C ++ , qui indique:

Type: size_t (type intégral non signé)

En-tête:

size_t correspond au type de données intégral renvoyé par l’opérateur sizeof opérateur de langue et est défini dans le fichier d’en-tête (entre autres) comme un type intégral non signé.

Dans , il est utilisé comme type du paramètre num dans les fonctions memchr , memcmp , memcpy , memmove , memset , strncat , strncmp , strncpy et strxfrm , qui dans tous les cas est utilisé pour spécifier le nombre maximal d’octets. ou caractères que la fonction doit affecter.

Il est également utilisé comme type de retour pour strcspn , strlen , strspn et strxfrm pour renvoyer des tailles et des longueurs.

size_t devrait être défini dans les en-têtes de votre bibliothèque standard. D’après mon expérience, il s’agit généralement d’un typedef à unsigned int. Le point, cependant, est que cela ne doit pas être. Des types tels que size_t permettent au fournisseur de bibliothèque standard de modifier ses types de données sous-jacents, le cas échéant, pour la plate-forme. Si vous supposez que size_t est toujours unsigned int (par casting, etc.), vous pourriez rencontrer des problèmes à l’avenir si votre fournisseur modifie size_t pour qu’il soit par exemple un type 64 bits. Il est dangereux de supposer quelque chose à ce sujet ou tout autre type de bibliothèque pour cette raison.

Je ne suis pas familier avec void_t sauf à la suite d’une recherche sur Google (il est utilisé dans une bibliothèque vmalloc par Kiem-Phong Vo chez AT & T Research – je suis sûr qu’il est également utilisé dans d’autres bibliothèques).

Les différents typedefs xxx_t sont utilisés pour extraire un type d’une implémentation définie particulière, car les types concrets utilisés pour certaines choses peuvent différer d’une plateforme à l’autre. Par exemple:

  • size_t abstrait le type utilisé pour contenir la taille des objects car sur certains systèmes, il s’agira d’une valeur de 32 bits, d’autres de 16 ou de 64 bits.
  • Void_t extrait le type de pointeur renvoyé par les routines de la bibliothèque vmalloc car il a été écrit pour fonctionner sur des systèmes antérieurs à ANSI / ISO C où le mot clé void peut ne pas exister. Au moins c’est ce que je suppose.
  • wchar_t abstrait le type utilisé pour les caractères larges, car sur certains systèmes, il s’agira d’un type 16 bits, d’autres de 32 bits.

Donc, si vous écrivez votre code de gestion de caractères larges pour utiliser le type wchar_t au lieu de, disons unsigned short , ce code sera probablement plus portable sur différentes plates-formes.

Dans les programmes minimalistes où une définition de size_t n’était pas chargée “par hasard” dans certaines inclus, mais j’en ai toujours besoin dans un certain contexte (par exemple pour accéder à std::vector ), j’utilise ce contexte pour extraire le type correct. Par exemple, typedef std::vector::size_type size_t .

(Entourez avec un namespace {...} de namespace {...} si nécessaire pour limiter la scope.)

Comme pour “Pourquoi ne pas utiliser int ou unsigned int?”, Simplement parce que c’est sémantiquement plus significatif de ne pas le faire. Il y a une raison pratique pour laquelle il peut être, par exemple, typedef d en tant int et ensuite mis à jour long plus tard, sans que personne n’ait à modifier son code, bien sûr, mais plus fondamentalement qu’un type est censé être significatif. Pour simplifier énormément, une variable de type size_t convient et contient les tailles d’objects, tout comme time_t convient pour contenir des valeurs temporelles. La manière dont elles sont effectivement mises en œuvre devrait très bien être le travail de mise en œuvre. Comparativement au simple fait d’appeler tout ce qui est int , utiliser des noms de caractères significatifs comme celui-ci permet de clarifier la signification et l’intention de votre programme, comme le fait tout ensemble riche de types.