153 votes

Quelle est la taille du bit de long sous Windows 64 bits ?

Il n'y a pas si longtemps, quelqu'un m'a dit que long ne sont pas 64 bits sur des machines 64 bits et je devrais toujours utiliser int . Cela n'a pas de sens pour moi. J'ai vu des documents (comme celui sur le site officiel d'Apple) qui disent que long sont effectivement 64 bits lorsqu'ils sont compilés pour un CPU 64 bits. J'ai cherché ce que c'était sous Windows 64 bits et j'ai trouvé

  • Les fenêtres : long y int restent d'une longueur de 32 bits, et de nouveaux types de données spéciaux sont définis pour les entiers de 64 bits.

(de http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )

Que dois-je utiliser ? Devrais-je définir quelque chose comme uw , sw (largeur (non)signée) en tant que long si ce n'est pas sous Windows, et sinon faire une vérification du bitsize du CPU cible ?

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

0 votes

@SergeRogatch ils devraient utiliser size_t ou un type d'itérateur pour itérer, et non pas int o int64_t

280voto

Jonathan Leffler Points 299946

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.

13 votes

Pour ceux d'entre nous qui sont là depuis assez longtemps, la transition vers le 64 bits présente certains parallèles avec la transition du 16 bits au 32 bits au milieu des années 80. Il y avait des ordinateurs qui étaient IL32 et d'autres qui étaient L32 (adaptant la nouvelle notation à l'ancien problème). Parfois, "int" était 16 bits, parfois 32 bits.

4 votes

N'oubliez pas que cela ne s'applique qu'aux langages C-ish. D'autres ont des spécifications plus saines où a) l'auteur du compilateur n'est pas autorisé à choisir la taille des types de données bon gré mal gré ou b) la représentation physique des types de données ne "fuit" pas ou c) les entiers sont toujours infiniment grands.

2 votes

C'est vrai - mais pour les langages qui spécifient le comportement, il n'y a pas de problème en premier lieu. Par exemple, Java a un "long", mais la taille est fixe (64 bits ?), sur toutes les plateformes. Il n'y a donc aucun problème de portage vers une machine 64 bits ; la taille ne change pas.

63voto

Martin Liversage Points 43712

Il n'est pas clair si la question porte sur le compilateur C++ de Microsoft ou sur l'API Windows. Cependant, comme il n'y a pas de balise [c++], je suppose qu'il s'agit de l'API Windows. Certaines des réponses ont souffert de la pourriture des liens, c'est pourquoi je vous propose un autre lien qui peut pourrir.


Pour des informations sur les types d'API Windows comme INT , LONG etc., il existe une page sur MSDN :

Types de données Windows

Ces informations sont également disponibles dans divers fichiers d'en-tête Windows tels que WinDef.h . J'en ai énuméré quelques types pertinents ici :

Type                        | S/U | x86    | x64
----------------------------+-----+--------+-------
BYTE, BOOLEAN               | U   | 8 bit  | 8 bit
----------------------------+-----+--------+-------
SHORT                       | S   | 16 bit | 16 bit
USHORT, WORD                | U   | 16 bit | 16 bit
----------------------------+-----+--------+-------
INT, LONG                   | S   | 32 bit | 32 bit
UINT, ULONG, DWORD          | U   | 32 bit | 32 bit
----------------------------+-----+--------+-------
INT\_PTR, LONG\_PTR, LPARAM   | S   | 32 bit | 64 bit
UINT\_PTR, ULONG\_PTR, WPARAM | U   | 32 bit | 64 bit
----------------------------+-----+--------+-------
LONGLONG                    | S   | 64 bit | 64 bit
ULONGLONG, QWORD            | U   | 64 bit | 64 bit

La colonne "S/U" indique qu'il s'agit d'un diplôme signé/non signé.

6voto

Fahrenheit2539 Points 1809

À propos, si vous devez faire face à des compilateurs qui utilisent différentes tailles de long et que vous avez des tonnes de code à porter, vous pourriez vouloir le vérifier avec l'outil appelé PVS-Studio . Il dispose d'un message de diagnostic spécifique (V126) pour signaler de telles situations.

5voto

reuben Points 2598

Cet article sur MSDN fait référence à un certain nombre d'alias de type (disponibles sur 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 de 64 bits, vous pouvez également utiliser UINT64. (Il en va de même pour ULONG et UINT32.) Peut-être cela sera-t-il un peu plus clair ?

1 votes

Existe-t-il une garantie que les uint32_t et les DWORD seront interchangeables ? Il n'est pas difficile d'imaginer qu'ils puissent ne pas l'être (par exemple, si le premier est un fichier 32 bits, le second est un fichier de données). int et le dernier un 32-bit long En effet, gcc supposerait qu'un pointeur vers un type ne pourrait pas aliaser l'autre type malgré leurs représentations correspondantes].

5voto

Mark Ransom Points 132545

Microsoft a également défini UINT_PTR et INT_PTR pour les entiers qui ont la même taille qu'un pointeur.

Voici un liste des types spécifiques à Microsoft - Cela fait partie de leur référence pour les pilotes, mais je pense que c'est également valable pour la programmation générale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X