Il n'y a pas si longtemps, quelqu'un m'a dit que ce long
ne sont pas des 64 bits sur des machines 64 bits et que je devrais toujours les utiliser int
. Cela n'avait aucun sens pour moi. J'ai vu des documents (comme celui sur le site officiel d'Apple) dire qu'il long
s'agit bien de 64 bits lors de la compilation pour un processeur 64 bits. J'ai cherché ce que c'était sur Windows 64 bits et j'ai trouvé
- Windows:
long
etint
restent 32 bits de longueur, et de nouveaux types de données spéciaux sont définis pour les entiers 64 bits.
(à partir de http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )
Que dois-je utiliser? Dois-je définir quelque chose comme uw
, sw
(largeur (non) signée) comme long
si ce n'est pas sous Windows, et sinon faire une vérification sur la taille en bits du processeur cible?
sizeof(long) == 8
, même sous Windows :-)size_t
ou un type d'itérateur pour itérer, pasint
ouint64_t
size_t
cela devient délicat près des nombres négatifs, car ilsize_t
n'est pas signé. Doncfor(size_t i=0; i<v.size()-2; i++)
échoue pour la taille du vecteur 0 et 1. Un autre exemple:for(size_t i=v.size()-1; i>=0; i--)
.size_t
valeurs, le résultat doit être conservé dans une variable deptrdiff_t
type - qui est conçue pour être suffisamment grande pour contenir un tel résultat et est un type signé précisément pour cette raison!)Réponses:
Dans le monde Unix, il y avait quelques arrangements possibles pour les tailles d'entiers et de pointeurs pour les plates-formes 64 bits. Les deux les plus largement utilisés étaient ILP64 (en fait, seuls quelques exemples de cela; Cray en était un) et LP64 (pour presque tout le reste). Les acronynms proviennent de «int, long, les pointeurs sont 64 bits» et «longs, les pointeurs sont 64 bits».
Le système ILP64 a été abandonné au profit de LP64 (c'est-à-dire que presque tous les nouveaux venus ont utilisé LP64, sur la base des recommandations du groupe Aspen; seuls les systèmes avec un long héritage d'exploitation 64 bits utilisent un schéma différent). Tous les systèmes Unix 64 bits modernes utilisent LP64. MacOS X et Linux sont tous deux des systèmes 64 bits modernes.
Microsoft utilise un schéma différent pour la transition vers 64 bits: LLP64 («long long, les pointeurs sont 64 bits»). Cela a le mérite de signifier que les logiciels 32 bits peuvent être recompilés sans changement. Il a l'inconvénient d'être différent de ce que tout le monde fait et nécessite également une révision du code pour exploiter les capacités 64 bits. Il y avait toujours une révision nécessaire; c'était juste un ensemble de révisions différent de ceux nécessaires sur les plates-formes Unix.
Si vous concevez votre logiciel autour de noms de type entiers neutres de la plate-forme, probablement en utilisant l'en-
<inttypes.h>
tête C99 , qui, lorsque les types sont disponibles sur la plate-forme, fournit, en signé (listé) et non signé (non listé; préfixe avec 'u'):int8_t
- Entiers 8 bitsint16_t
- Entiers 16 bitsint32_t
- Entiers 32 bitsint64_t
- Entiers 64 bitsuintptr_t
- entiers non signés assez grands pour contenir des pointeursintmax_t
- plus grande taille d'entier sur la plate-forme (peut être plus grande queint64_t
)Vous pouvez ensuite coder votre application en utilisant ces types là où cela compte, et en faisant très attention aux types de système (qui peuvent être différents). Il existe un
intptr_t
type - un type entier signé pour contenir des pointeurs; vous devez prévoir de ne pas l'utiliser, ou de ne l'utiliser qu'à la suite d'une soustraction de deuxuintptr_t
valeurs (ptrdiff_t
).Mais, comme le souligne la question (incrédule), il existe différents systèmes pour les tailles des types de données entiers sur les machines 64 bits. Habituez-vous à cela; le monde ne va pas changer.
la source
short
, comment appelez-vous le type 16 bits? Et si vous appelez le type 16 bitschar
pour UTF-16, etc., comment appelez-vous le type 8 bits? Ainsi, l'utilisation de LP64 vous laisse avec 8 bitschar
, 16 bitsshort
, 32 bitsint
, 64 bitslong
, avec de la place pour une extension vers le haut à 128 bitslong long
lorsque (si?) Cela devient pertinent. Après cela, vous avez plus de puissances de 256 que de noms en C (enfin, je suppose que vous pourriez avoir un 256 bitsintmax_t
, et alors seulement vous en manquez). Il y a du mérite à LP64.Il n'est pas clair si la question concerne le compilateur Microsoft C ++ ou l'API Windows. Cependant, il n'y a pas de balise [c ++] donc je suppose qu'il s'agit de l'API Windows. Certaines des réponses ont souffert de la pourriture des liens, je fournis donc un autre lien qui peut pourrir.
Pour plus d'informations sur les types d'API Windows comme
INT
,LONG
etc., il existe une page sur MSDN:Types de données Windows
Les informations sont également disponibles dans divers fichiers d'en-tête Windows comme
WinDef.h
. J'ai répertorié quelques types pertinents ici:La colonne «S / U» indique signé / non signé.
la source
Cet article sur MSDN fait référence à un certain nombre d'alias de type (disponibles sous Windows) qui sont un peu plus explicites en ce qui concerne leur largeur:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Par exemple, bien que vous puissiez utiliser ULONGLONG pour référencer une valeur intégrale non signée 64 bits, vous pouvez également utiliser UINT64. (Il en va de même pour ULONG et UINT32.) Peut-être que ce sera un peu plus clair?
la source
int
et le second un 32 bitslong
, gcc supposerait qu'un pointeur vers un type serait incapable d'aliaser l'autre malgré leurs représentations correspondantes].Microsoft a également défini UINT_PTR et INT_PTR pour les entiers de la même taille qu'un pointeur.
Voici une liste de types spécifiques à Microsoft - cela fait partie de leur référence de pilote, mais je pense que c'est également valable pour la programmation générale.
la source
Le moyen le plus simple de le connaître pour votre compilateur / plateforme:
La multiplication par 8 consiste à obtenir des bits à partir d'octets.
Lorsque vous avez besoin d'une taille particulière, il est souvent plus simple d'utiliser l'un des types prédéfinis d'une bibliothèque. Si cela n'est pas souhaitable, vous pouvez faire ce qui se passe souvent avec le logiciel autoconf et demander au système de configuration de déterminer le bon type pour la taille requise.
la source
La taille en bits de
long
sur les plates-formes Windows est de 32 bits (4 octets).Vous pouvez vérifier cela en utilisant
sizeof(long)
.la source
Si vous avez besoin d'utiliser des entiers d'une certaine longueur, vous devriez probablement utiliser des en-têtes indépendants de la plate-forme pour vous aider. Boost est un bon endroit à regarder.
la source