Pourquoi ssize_t dans Visual Studio 2010 est défini comme non signé?
J'ai un programme portable qui utilise ssize_t en vertu de l'hypothèse qu'il est un entier signé. Sur le plan conceptuel, il fait quelque chose comme:
#include <stdint.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
size_t size_10 = 10;
size_t size_20 = 20;
ssize_t len_diff;
len_diff = (ssize_t)size_10 - (ssize_t)size_20;
if (len_diff < 0)
printf("negative\n");
else if (len_diff > 0)
printf("positive\n");
else
printf("zero\n");
}
On pourrait croire que le programme d'impression "négatif", mais au lieu de l'impression "positive". La raison en est facile de voir à partir de combien de ssize_t est défini (dans sourceannotations.h):
#ifndef _SSIZE_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 ssize_t;
#else
typedef _W64 unsigned int ssize_t;
#endif
#define _SSIZE_T_DEFINED
#endif
Et donc, de la soustraction de deux valeurs non signées résultats dans un unsigned de la valeur et donc le résultat.
Dans les anciennes versions du SDK de Windows (par exemple V7.0A) le ssize_t a été correctement définie comme:
//
//SIZE_T used for counts or ranges which need to span the range of
//of a pointer. SSIZE_T is the signed variation.
//
typedef ULONG_PTR SIZE_T, *PSIZE_T;
typedef LONG_PTR SSIZE_T, *PSSIZE_T;
Quelqu'un peut expliquer ce changement? Sommes-nous censés cesser d'utiliser ssize_t sur Windows?
Mise à jour:
Basé sur toutes les réponses, il semble être un bogue dans Visual Studio 2010 qui comprend ssize_t mais pas correctement défini. C'est un sournois et méchant bug.
Dernière Mise À Jour:
Ce bogue a été corrigé dans VS2012 et VS2016. Également dans le commentaire la discussion, il apparaît que cette méthode de calcul de la len_diff est problématique lorsque les valeurs comparées sont de signes différents lors coulé à SSIZE_T
Ainsi, le "ou". 🙂
assez. C'est vraiment assez fou qu'ils ont défini le connecté version de
size_t
non signés.Il me semble que le tout-caps, MS-style
SSIZE_T
est correct et c'est juste la POSIX-style ssize_t
c'est cassé, donc je suppose que c'est encore un autre subtile de tenter de casser le portable de la croix-code plate-forme et de la force spécifique à Windows #ifdef
s...Mentionnés
ssize_t
buggy définition n'est pas présent dans VC2012OriginalL'auteur Dror Harari | 2014-03-08
Vous devez vous connecter pour publier un commentaire.
ssize_t
est pas C standard, c'est une définition de type de Posix. Que vous l'avez trouvé dans une analyse de code d'en-tête pour VS2010 a probablement quelque chose à voir avec l'origine, la plupart de l'analyse du code de l'outillage commencé sur Unix. Il est supprimé à nouveau dans VS2012 et.Qu'il est présent dans la BaseTsd.h SDK fichier dans tous les bouchons n'est certainement pas une erreur, Windows pris en charge un sous-système Posix. Ces typedefs isoler le système d'exploitation de compilateur détails de mise en œuvre, la raison fondamentale que Windows a réussi à survivre à des modifications de l'architecture, de passer de 16 à 32 à 64 bits.
De sorte que le réel problème, c'est que vous essayez de compiler un programme Posix sur Windows, mais sans l'aide de Posix en-têtes. Trivial à résoudre, il suffit d'ajouter votre propre typedef avant les #includes.
OriginalL'auteur
Serait-ce une bonne solution?
#if __INTELLISENSE__
. Merci.OriginalL'auteur
Bien que c'est franchement pas conforme à la norme POSIX avoir
ssize_t
étant un entier non signé, l'OP du code des risques aussi sur les systèmes conformes à la norme POSIX.Que POSIX définit
ssize_t
pour juste couvrir le-1
et rien d'autre négatif:size_t
mais avec une valeur réservée pour le traitement des erreurs?Ma conjecture est que si la valeur est trop grande pour le nombre de bits, -1 est utilisé comme un débordement de la titulaire et errstr
size_t
etssize_t
sont juste cassé la normalisation, très difficile de les mélanger à 100% de façon portable, car ils ont une portée différente de la possible des valeurs positives. Il devrait être l'un d'entre eux pour faciliter l'écriture de code robuste.Oui, les cas d'utilisation typique de
ssize_t
est pour la valeur de retour deread(2)
.Oui, je veux voir la puce designer qui, jjust pour le coup, développer un CPU avec une base de type scalaire correspondant à cette SSIZE_T définition couvrant l'intervalle [-1, {SSIZE_MAX}]. Cependant, vous avez soulevé un point que le code est problématique dans le cas où les valeurs de traverser la moitié de la valeur de la unsigned quantité. La comparaison des pauses à travers ce que d'un demi-point par exemple avec le coulé valeurs 1, 10, -10, -1 -- ici, nous allons obtenir (1,10)=>Négatif, (10,-10)=>Positif, qui serait un bug dans le code d'origine)
OriginalL'auteur