Question

Je remarque que le code C et C ++ moderne semble utiliser size_t au lieu de int / unsigned int un peu partout - des paramètres pour les fonctions de chaîne C à la STL. Je suis curieux de savoir la raison de cela et les avantages que cela apporte.

Était-ce utile?

La solution

Le type size_t est le type entier non signé qui est le résultat de l'opérateur sizeof (et de l'opérateur offsetof). Il est donc garanti qu'il soit suffisamment grand pour contenir la taille du plus gros objet de votre système. peut gérer (par exemple, un tableau statique de 8 Go).

Le type unsigned int peut être supérieur, égal ou inférieur à <=>, et votre compilateur peut en déduire des hypothèses d'optimisation.

Vous trouverez des informations plus précises à la section 7.17 du standard C99, dont un projet est disponible sur Internet sous format pdf , ou dans la norme C11, section 7.19, également disponible en tant que brouillon pdf .

Autres conseils

Classic C (le premier dialecte du C décrit par Brian Kernighan et Dennis Ritchie dans le langage de programmation C, Prentice-Hall, 1978) n'a pas fourni size_t. Le comité des normes C a introduit <=> pour éliminer un problème de portabilité

expliqué en détail sur embedded.com (avec un très bon exemple)

En bref, size_t n’est jamais négatif et optimise les performances car son type est typé comme un entier non signé suffisamment grand - mais pas trop grand - pour représenter la taille du plus grand objet possible sur le plate-forme cible.

Les tailles ne doivent jamais être négatives. En effet, unsigned int est un type non signé. De plus, étant donné que 4294967295 est non signé, vous pouvez stocker des nombres environ deux fois plus grands que dans le type signé, car nous pouvons utiliser le bit de signe pour représenter la magnitude, comme tous les autres bits de l'entier non signé. Lorsque nous gagnons un bit de plus, nous multiplions la plage de nombres que nous pouvons représenter par un facteur d'environ deux.

Alors, vous vous demandez, pourquoi ne pas utiliser simplement un unsigned long int? Il ne sera peut-être pas capable de contenir suffisamment de nombres. Dans une implémentation où long est 32 bits, le plus grand nombre qu'il peut représenter est unsigned long. Certains processeurs, tels que l'IP16L32, peuvent copier des objets d'une taille supérieure à unsigned long long octets.

Alors, vous vous demandez, pourquoi ne pas utiliser un <=>? Cela impose des performances sur certaines plates-formes. La norme C exige qu’un <=> occupe au moins 32 bits. Une plate-forme IP16L32 implémente chaque longueur de 32 bits sous la forme d'une paire de mots de 16 bits. Presque tous les opérateurs 32 bits sur ces plates-formes requièrent deux instructions, sinon plus, car ils fonctionnent avec les 32 bits en deux morceaux de 16 bits. Par exemple, déplacer une longueur de 32 bits nécessite généralement deux instructions machine, une pour déplacer chaque bloc de 16 bits.

L'utilisation de <=> évite ces problèmes de performances. Selon cet article fantastique , < !> quot; Type <=> est une typedef qui est un alias pour un type d’entier non signé, généralement <=> ou <=>, mais peut-être même <=>. Chaque implémentation Standard C est supposée choisir un nombre entier non signé suffisamment grand - mais pas plus grand que nécessaire - pour représenter la taille du plus grand objet possible sur la plate-forme cible. & Quot;

Le type size_t est le type renvoyé par l'opérateur sizeof. Il s'agit d'un entier non signé capable d'exprimer la taille en octets de toute plage de mémoire prise en charge sur la machine hôte. Il est (généralement) lié à ptrdiff_t en ce que ptrdiff_t est une valeur entière signée telle que sizeof (ptrdiff_t) et sizeof (size_t) sont égaux.

Lorsque vous écrivez du code C, vous devez toujours utiliser size_t pour gérer les plages de mémoire.

Le type int, quant à lui, est fondamentalement défini comme la taille de la valeur entière (signée) que la machine hôte peut utiliser pour exécuter efficacement l'arithmétique des entiers. Par exemple, sur de nombreux ordinateurs de type PC plus anciens, la valeur sizeof (size_t) serait de 4 (octets) mais sizeof (int) de 2 (octets). L’arithmétique 16 bits était plus rapide que l’arithmétique 32 bits, bien que la CPU puisse gérer un espace mémoire (logique) allant jusqu’à 4 Go.

Utilisez le type int uniquement lorsque vous vous souciez de l'efficacité car sa précision réelle dépend fortement des options du compilateur et de l'architecture de la machine. En particulier, la norme C spécifie les invariants suivants: sizeof (char) & Lt; = sizeof (court) & Lt; = sizeof (int) & Lt; = sizeof (long) n'imposant aucune autre limitation à la représentation réelle de la précision disponible pour le programmeur pour chacun de ces types primitifs.

Remarque: il ne s'agit PAS de la même chose qu'en Java (qui spécifie en fait la précision en bits de chacun des types "char", "octet", "court", "int" et "long").

Le type size_t doit être suffisamment grand pour stocker la taille de tout objet possible. Unsigned int ne doit pas nécessairement satisfaire à cette condition.

Par exemple, dans les systèmes 64 bits, int et unsigned int peuvent avoir une largeur de 32 bits, mais size_t doit être suffisamment grand pour stocker des nombres supérieurs à 4G

Cet extrait du manuel de la glibc 0.02 peut également être utile lors de la recherche du sujet:

Il existe un problème potentiel avec le type size_t et les versions de GCC antérieures à la version 2.4. ANSI C requiert que size_t soit toujours un type non signé. Pour assurer la compatibilité avec les fichiers d’en-tête des systèmes existants, GCC définit size_t dans stddef.h' to be whatever type the system's sys / types.h '. La plupart des systèmes Unix qui définissent size_t dans `sys / types.h ', définissent le type signé. Certains codes de la bibliothèque dépendent du fait que size_t est un type non signé et ne fonctionnera pas correctement s’il est signé.

Le code de la bibliothèque GNU C qui attend que size_t ne soit pas signé est correct. La définition de size_t en tant que type signé est incorrecte. Nous prévoyons que dans la version 2.4, GCC définira toujours size_t en tant que type non signé et le fixincludes' script will massage the system's sys / types.h 'afin de ne pas entrer en conflit avec cela.

Dans l'intervalle, nous contournons ce problème en indiquant explicitement à GCC d'utiliser un type non signé pour size_t lors de la compilation de la bibliothèque GNU C. `configure 'détectera automatiquement le type utilisé par GCC pour size_t, arrangez-le pour le remplacer si nécessaire.

Si mon compilateur est défini sur 32 bits, size_t n’est rien d’autre qu’un typedef pour unsigned int. Si mon compilateur est défini sur 64 bits, unsigned long long n’est rien d’autre qu’un typedef pour <=>.

size_t est la taille d'un pointeur.

Donc, dans 32 bits ou le ILP32 commun (entier, long, pointeur), le modèle size_t est 32 bits. et dans 64 bits ou le modèle LP64 commun (long, pointeur), le modèle size_t correspond à 64 bits (les entiers ont encore 32 bits).

Il existe d'autres modèles, mais ceux-ci sont ceux que g ++ utilise (au moins par défaut)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top