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.).
@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 .
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.
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.)
@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».
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.
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.
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.
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.
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.)
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.
Réponses:
De Wikipedia
À partir de C99 7.17.1 / 2
la source
int
et lesunsigned 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:la source
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é) estsize_t
(ISO C99 Section 6.5.3.4.)la source
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-ciuint
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 fichiersize_t
. Par exemple, des éléments comme les tailles de tableaux doivent toujours utilisersize_t
des. Si vous regardez les conteneurs standard, le::size()
retourne toujours asize_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».
la source
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 ununsigned 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:
la source
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.
la source
Je ne suis pas familier avec
void_t
sauf à la suite d'une recherche Google (il est utilisé dans unevmalloc
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 lesvmalloc
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, disonsunsigned short
, ce code sera probablement plus portable sur diverses plates-formes.la source
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éderstd::vector<double>
), alors j'utilise ce contexte pour extraire le type correct. Par exempletypedef std::vector<double>::size_type size_t
.(Entourez-le
namespace {...}
si nécessaire pour limiter la portée.)la source
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 queint
et ensuite mis à niveau vers une versionlong
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 typesize_t
convient et est utilisée pour contenir les tailles des choses, tout commetime_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 toutint
, 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.la source