Dans le monde Unix, il y avait quelques arrangements possibles pour les tailles des entiers et des pointeurs pour les plateformes 64 bits. Les deux plus largement utilisées étaient ILP64 (en fait, il n'y a que très peu d'exemples de cela ; Cray en était un) et LP64 (pour presque tout le reste). Les acronymes viennent de "int, long, pointers are 64-bit" et "long, pointers are 64-bit".
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64
Le système ILP64 a été abandonné en faveur de LP64 (c'est-à-dire que presque tous les entrants ultérieurs ont utilisé LP64, sur la base des recommandations du groupe Aspen ; seuls les systèmes ayant un long héritage de fonctionnement en 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 le 64 bits : LLP64 ("long long, pointers are 64-bit"). Cela a le mérite de signifier que les logiciels 32 bits peuvent être recompilés sans changement. Il a le démérite 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 du 64 bits. Une révision a toujours été nécessaire ; c'était juste un ensemble de révisions différentes de celles nécessaires sur les plateformes Unix.
Si vous concevez votre logiciel en fonction de noms de types entiers neutres pour la plate-forme, en utilisant probablement la norme C99 <inttypes.h>
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 de 8 bits
-
int16_t
- Entiers de 16 bits
-
int32_t
- Entiers de 32 bits
-
int64_t
- Entiers de 64 bits
-
uintptr_t
- des entiers non signés suffisamment grands pour contenir des pointeurs
-
intmax_t
- la plus grande taille d'entier sur la plateforme (peut être plus grande que int64_t
)
Vous pouvez alors coder votre application en utilisant ces types là où c'est important, et en faisant très attention aux types du système (qui peuvent être différents). Il existe un intptr_t
type - un type d'entier signé pour contenir les pointeurs ; vous devriez prévoir de ne pas l'utiliser, ou de ne l'utiliser que comme résultat d'une soustraction de deux uintptr_t
valeurs ( ptrdiff_t
).
Mais, comme le souligne la question (avec incrédulité), il existe différents systèmes pour les tailles des types de données entières sur les machines 64 bits. Il faut s'y faire, le monde ne va pas changer.
1 votes
Sous Windows avec MSVC++, int et long sont 32 bits : msdn.microsoft.com/fr/us/library/3b2e7499.aspx . Cependant, pour permettre aux vecteurs, par exemple, de stocker plus de 4G d'éléments, size_t est de 64 bits. Il faut donc utiliser int64_t au lieu de int pour itérer, par exemple, des vecteurs qui peuvent contenir plus de 4G éléments.
3 votes
Sur Cygwin
sizeof(long) == 8
même sous Windows :-)0 votes
@SergeRogatch ils devraient utiliser
size_t
ou un type d'itérateur pour itérer, et non pasint
oint64_t
2 votes
@LuuVinhPhúc, avec
size_t
cela devient délicat à proximité de nombres négatifs, carsize_t
est non signée. Ainsi,for(size_t i=0; i<v.size()-2; i++)
échoue pour les vecteurs de taille 0 et 1. Autre exemple :for(size_t i=v.size()-1; i>=0; i--)
.3 votes
Si vous faites des maths sur des pointeurs (c'est-à-dire avec des
size_t
alors le résultat doit être conservé dans une variable de typeptrdiff_t
qui est conçu pour être suffisamment grand pour contenir un tel résultat et qui est une signé pour cette raison précise !)0 votes
@rustyx il s'agit de compilateurs, pas de systèmes d'exploitation. Cygwin est compilé en utilisant mingw (un portage de GCC sur Windows) comme compilateur. Comme GCC sur linux, il peut définir
long
comme 64 bits, mais MSVC++ (le compilateur de Microsoft) le définit comme 32 bits.1 votes
@OrionEdwards En fait, il s'agit de l'ABI de la plate-forme cible. Cygwin possède sa propre ABI de type POSIX et choisit le modèle LLP64 plus favorable à POSIX, alors que Mingw s'en tient à l'ABI Win32 avec son modèle LP64. Pour cette raison, dans GCC fourni avec Mingw
long
est de 32 bits et dans GCC dans Cygwin - 64 bits.0 votes
@rustyx J'ai l'impression qu'on se parle sans se parler. Ce que je veux dire, c'est que
long
n'existe que dans le monde du compilateur, et des conventions qu'il attend. Une fois que le code s'exécute, c'est juste "Il y a 8 octets à cette adresse", et les termes int, long, etc. n'existent pas.