Où trouver la définition de size_t?

123

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.).

Eliseo Ocampos
la source
Question exacte: stackoverflow.com/questions/502856/…
kjfletch
@kjfletch: hhhmmm, c'est bizarre que la recherche du terme 'size_t' (comme je l'ai fait précédemment) n'ait pas renvoyé cette question.
Eliseo Ocampos
1
@Eliseo - La fonction de recherche de Stackoverflow est horrible. Utilisez plutôt Google avec un paramètre "site: stackoverflow.com".
Michael Burr
8
L'OP a spécifiquement demandé où trouver la définition de size_t? J'ai atterri ici à la recherche de la même chose. Le dup cité ne discute pas de l'endroit où trouver la déclaration.
jww
9
Cette question n'est évidemment pas la même que celle liée. «Où puis-je trouver quelque chose» n'est pas la même chose que «Quelle est la différence entre» (même si la réponse à l'un fournit la réponse à l'autre). Ma recherche Google pour «c ++ où est la définition de size_t» m'a amené directement ici, et j'aurais manqué l'autre question, car elle est différente .
Dan Nissenbaum

Réponses:

122

De Wikipedia

Le stdlib.hetstddef.h fichiers d'en-tête définissent un type de données appelé size_t1 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 type size_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'il size_test 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

Martin Liversage
la source
2
Par exemple, sur Win64, intet les unsigned inttypes sont de 32 bits, tandis que size_t est de 64 bits.
Michael Burr
7
Veuillez vous référer à la norme ISO C (99) (à partir de laquelle la norme C ++ inclut) sections 7.17 et 7.18.3
Martin York
3
@LokiAstari pourquoi ne modifiez-vous pas simplement la réponse puisque vous savez où elle est écrite dans la norme?
Hi-Angel
Alors, où est la réponse C ++?
Lothar
@Lothar Je pense que la seule différence est que size_t peut être un mot-clé, et a par ailleurs la même signification.
Paul Stelian
30

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>
stefanB
la source
2
C'est exactement ce dont j'avais besoin, cette réponse devrait être votée pour.
neodelphi
27

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

L' sizeofopé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.)

fpmurphy
la source
La meilleure réponse car elle cite la norme.
Martin York
1
@Martin - assez vrai, mais je pense que la partie `` pourquoi n'est-ce pas un int unsigned utilisé '' de la question est aussi intéressante (ou plus) que la partie `` qu'est-ce que size_t '', et vous ne trouverez pas cela dans la norme .
Michael Burr
Ouais, sauf qu'il n'y a pas de «Section 17.17 »: p. C'est rare, personne n'a dit un mot sur Void_t
Eliseo Ocampos
J'accepte cette réponse car elle répond directement à la question, mais ce serait formidable qu'elle soit complétée par la réponse de Michael.
Eliseo Ocampos le
58
Dommage que votre réponse ne me dise pas quel fichier d'en-tête inclure.
Matt
6

size_tRepré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 uintrestera 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_tdes. 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».

Prix ​​de Matt
la source
2

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 intou 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_tcorrespond au type de données intégral renvoyé par l'opérateur de langage sizeofet 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ètre numdans les fonctions memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyetstrxfrm 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, strspnet strxfrmà la taille de retour et longueurs.

Lavinio
la source
2

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.

Ryan
la source
1

Je ne suis pas familier avec void_tsauf à la suite d'une recherche Google (il est utilisé dans une vmallocbibliothè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:

  • size_t fait abstraction du type utilisé pour contenir la taille des objets car sur certains systèmes, ce sera une valeur de 32 bits, sur d'autres, elle peut être de 16 bits ou 64 bits.
  • Void_trésume le type de pointeur renvoyé par les vmallocroutines 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_ttype au lieu de, disons unsigned short, ce code sera probablement plus portable sur diverses plates-formes.

Michael Burr
la source
C'est ce que je cherchais, en partie. Comme je l'ai dit dans un commentaire dans la réponse de fpmurphy, ce serait formidable qu'elle puisse être complétée par cette réponse (si cela ne vous dérange pas, vous pouvez peut-être la modifier) ​​:)
Eliseo Ocampos
1

Dans les programmes minimalistes où une size_tdé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.)

alfC
la source
1

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, typedefd en tant que intet ensuite mis à niveau vers une version longulté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_tconvient et est utilisée pour contenir les tailles des choses, tout comme time_tconvient 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.

Crowman
la source