C size_t et ssize_t valeur négative
size_t
est déclarée comme unsigned int
donc il ne peut pas représenter la valeur est négative.
Il est donc ssize_t
qui est le signé type de size_t
droit?
Voici mon problème:
#include <stdio.h>
#include <sys/types.h>
int main(){
size_t a = -25;
ssize_t b = -30;
printf("%zu\n%zu\n", a, b);
return 0;
}
pourquoi j'ai eu:
18446744073709551591
18446744073709551586
comme résultat?
Je sais qu'avec size_t
cela pourrait être possible parce que c'est un type non signé mais pourquoi j'ai eu un mauvais résultat aussi avec ssize_t
??
Vous utilisez la mauvaise spécificateur de format.
ssize_t
n'est pas dans la norme C, il vient de POSIX. La ferme en C standard qui vient à l' ssize_t
est ptrdiff_t
.size_t
est un unsigned type intégral, mais c'est usuall pas unsigned int
. Est généralement équivalent à unsigned long
ou unsigned long long
.OriginalL'auteur polslinux | 2012-08-29
Vous devez vous connecter pour publier un commentaire.
Dans le premier cas, vous êtes de l'affectation à un type non signé -
a
. Dans le second cas, vous utilisez la mauvaise spécificateur de format. La deuxième spécificateur devrait être%zd
au lieu de%zu
.printf("%zu", b)
s'attend à un nombre entier desizeof(size_t)
, sizeof(size_t) toujours le même que sizeof(ssize_t) de ne pas faire des bêtises? Ou estprintf("%zu", (size_t) b)
nécessaire?Est
ssize_t
défini pour être de la même taille quesize_t
? Si non,"%zd"
n'est pas un portable réponse. Suggérerprintf("%jd\n", (intmax_t) b);
est le spécificateur prescrit pour
ssize_t
. Une conversion entière suivante correspond à unsize_t
oussize_t
argument.Merci. Comme
ssize_t
n'est pas spécifié dans C, où pourrais-je trouver que"%zd"
spécificateur de prescription de référence pour l'avenir?J'ai cité un linux page de man printf. standard aussi fait mention, mais pas aussi clairement.
OriginalL'auteur cnicutar
Tout d'abord, vous devez vérifier la taille réelle des deux types.
Quelque chose comme l'extrait de code suivant devrait le faire:
- Je obtenir (64 bits Linux, GCC v7.2) "8 octets" dans les deux cas, qui est le même que le long int et long long int, le maximum de CPU-native valeur entière.
Quand les tailles sont les mêmes (et ils devraient toujours l'être),
size_t
peut avoir "2x plus grande des valeurs absolues" quessize_t
qui, à son tour, peut avoir signé (qui est soit positive ou négative).S'ils étaient différents, alors la plus grande, la " plus grande et pourrait donc accueillir pour de plus grandes valeurs.
Mais à la fin,
ssize_t
etsize_t
sont deux différents types utilisés pour "parler" à propos de la taille, la longueur, la quantité de mémoire et ainsi de suite.Le premier est juste un amerrissage 1 bits pour la valeur afin d'obtenir le signe nécessaire à une sorte de signal d'erreur.
Enfin, les deux types ne sont pas interchangeables, pas toujours, au moins.
Lorsque la taille peut aller au-delà de 2^63 octets/articles la différence est claire.
size_t
ne débordera pas toutssize_t
volonté.Dans des circonstances normales, vous pouvez convertir de l'un à l'autre.
Pour le cas que j'ai mentionné plus tôt, vous devriez ne jamais les mélanger.
Tout comme une référence, à la fois
strlen()
etmalloc()
utilisationsize_t
, tandis que les deuxread()
etreadv()
utilisation ssize_t.Donc,
ssize_t
n'est pas la version signée desize_t
comme ils ont le non-chevauchement des royaumes.Alors, à vos questions, les deux nombres que vous voyez diffèrent par 5 unités, c'est exactement ce que vous attendez. Ce que vous voyez est la valeur de ces deux variables quand il est vu comme
unsigned long
. Essayez de les imprimer commesigned long
(%ld
) à la place.Malgré les (mauvaises) libellé,
z
est un modificateur de longueur, pas un indicateur de conversion. À mon humble avis, je voudrais utiliser%ld
ou%lu
basé sur leur utilisation et de leur signification. Mais c'est également soumis à des goûts personnels."ils ont non-cumul des royaumes." - faux, ils se chevauchent et les nombres 0, 1, 2, 3... sont dans le chevauchement de la partie
Ah ah ah!
:-D
Sûr. Je voulais dire que les fonctions d'utilisersize_t
oussize_t
, jamais les deux tmk.OriginalL'auteur EnzoR
Utilisation
Correspondent prescripteur, qui, pour un négatif
ssize_t
est pas%zu
.ssize_t
n'ont pas de C d'impression spécifié spécificateur. C n'a même pas de spécifierssize_t
.Différentes extensions de C ne spécifiez
ssize_t
et dans un cas de Linux, l'impression spécificateur aussi.Manuel du Programmeur Linux n'ont:
POSIX B. 2.12 Types De Données a
Depuis
ssize_t
peut (rarement) être plus large quesize_t
, à l'aide de"%zd"
peut invoquer comportement indéfini (UB). Il est assez simple de jeter la plus large standard type signé depuis C99 commeintmax_t
et d'impression.OriginalL'auteur chux
Débordement coz size_t est un UNSIGNED
lorsque vous essayez de définir size_t comme (-val)
vous obtenez de débordement et d'obtenir SIZE_T_MAX - val
par exemple:
size_t val = -20;
//val == 18446744073709551615 - 20;
OriginalL'auteur Bro