Je vois des variables définies avec ce type mais je ne sais pas d'où il vient, ni quel est son but. Pourquoi ne pas utiliser int ou unsigned int? (Qu'en est-il des autres types "similaires"? Void_t, etc.).
Je vois des variables définies avec ce type mais je ne sais pas d'où il vient, ni quel est son but. Pourquoi ne pas utiliser int ou unsigned int? (Qu'en est-il des autres types "similaires"? Void_t, etc.).
Réponses:
De Wikipedia
Le
stdlib.h
etstddef.h
fichiers d'en-tête définissent un type de données appelésize_t
1 qui est utilisé pour représenter la taille d'un objet. Les fonctions de bibliothèque qui prennent des tailles s'attendent à ce qu'elles soient de typesize_t
, et l'opérateur sizeof est évalué àsize_t
.Le type réel de
size_t
dépend de la plate-forme; une erreur courante consiste à supposer qu'ilsize_t
est identique à unsigned int, ce qui peut entraîner des erreurs de programmation, 2 d' autant plus que 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
<snip>
size_t
qui est le type entier non signé du résultat de l'opérateur sizeof
int
et les unsigned int
types sont de 32 bits, tandis que size_t est de 64 bits.
Selon la description de size_t sur en.cppreference.com, elle size_t
est définie dans les en-têtes suivants:
std::size_t
...
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
size_t
est le type entier non signé du résultat de l'opérateur sizeof (ISO C99 Section 7.17.)
L' sizeof
opérateur 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 entier non signé) est size_t
(ISO C99 Section 6.5.3.4.)
size_t
Représente pratiquement le nombre d'octets que vous pouvez adresser. Sur la plupart des architectures modernes au cours des 10 à 15 dernières années, il s'agissait de 32 bits, ce qui avait également la taille d'un int non signé. Cependant, nous passons à l'adressage 64 bits alors que celui-ci uint
restera très probablement à 32 bits (sa taille n'est pas garantie dans le standard c ++). Pour rendre votre code qui dépend de la taille de la mémoire portable entre les architectures, vous devez utiliser un fichier size_t
. Par exemple, des éléments comme les tailles de tableaux doivent toujours utiliser size_t
des. Si vous regardez les conteneurs standard, le ::size()
retourne toujours a size_t
.
Notez également que Visual Studio dispose d'une option de compilation qui peut vérifier ces types d'erreurs appelées «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 l'ampleur ( short
, int
,long
, etc.)?
Étant donné qu'un type spécifique est attribué, vous n'avez pas à vous soucier de la longueur ou de la signature.
La définition réelle peut être trouvée dans la bibliothèque de référence C ++ , qui dit:
Type:
size_t
(type intégral non signé)Entête:
<cstring>
size_t
correspond au type de données intégral renvoyé par l'opérateur de langagesizeof
et est défini dans le<cstring>
fichier d' tête (entre autres) comme un type intégral non signé.Dans
<cstring>
, il est utilisé comme le type de paramètrenum
dans les fonctionsmemchr
,memcmp
,memcpy
,memmove
,memset
,strncat
,strncmp
,strncpy
etstrxfrm
qui dans tous les cas , il est utilisé pour spécifier le nombre maximum d'octets ou des caractères de la fonction doit affecter.Il est également utilisé comme type de retour
strcspn
,strlen
,strspn
etstrxfrm
à la taille de retour et longueurs.
size_t doit ê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 simplement d'un typedef à unsigned int. Le fait est cependant que cela ne doit pas être le cas. Des types tels que size_t permettent au fournisseur de bibliothèques standard de modifier ses types de données sous-jacents si cela est approprié pour la plate-forme. Si vous supposez que size_t est toujours un int non signé (via la conversion, etc.), vous pourriez rencontrer des problèmes à l'avenir si votre fournisseur change size_t pour être par exemple un type 64 bits. Il est dangereux de supposer quoi que ce soit à propos de ce type de bibliothèque ou de tout autre type de bibliothèque pour cette raison.
Je ne suis pas familier avec void_t
sauf à la suite d'une recherche Google (il est utilisé dans une vmalloc
bibliothèque par Kiem-Phong Vo à 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 à une autre. Par exemple:
Void_t
résume le type de pointeur renvoyé par les vmalloc
routines de la bibliothèque car il a été écrit pour fonctionner sur des systèmes antérieurs à ANSI / ISO C où levoid
mot-clé peut ne pas exister. Du moins c'est ce que je suppose.wchar_t
fait abstraction du type utilisé pour les caractères larges puisque sur certains systèmes, ce sera un type 16 bits, sur d'autres, ce sera un type 32 bits.Donc, si vous écrivez votre code de gestion des caractères larges pour utiliser le wchar_t
type au lieu de, disons unsigned short
, ce code sera probablement plus portable sur diverses plates-formes.
Dans les programmes minimalistes où une size_t
définition n'a pas été chargée "par hasard" dans certains include mais j'en ai encore besoin dans un certain contexte (par exemple pour accéder std::vector<double>
), alors j'utilise ce contexte pour extraire le type correct. Par exemple typedef std::vector<double>::size_type size_t
.
(Entourez-le namespace {...}
si nécessaire pour limiter la portée.)
Quant à "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 la raison pratique pour laquelle il peut être, disons, typedef
d en tant que int
et ensuite mis à niveau vers une version long
ultérieure, sans que personne n'ait à changer son code, bien sûr, mais plus fondamentalement qu'un type est censé être significatif. Pour simplifier considérablement, une variable de type size_t
convient et est utilisée pour contenir les tailles des choses, tout comme time_t
convient pour contenir des valeurs de temps. La manière dont ceux-ci sont réellement mis en œuvre devrait tout à fait être le travail de la mise en œuvre. Comparé au simple appel de tout int
, l'utilisation de noms de types significatifs comme celui-ci permet de clarifier la signification et l'intention de votre programme, comme le fait tout ensemble de types riche.