web-dev-qa-db-fra.com

Quelle est la taille de bit de long sur 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 que je devrais toujours utiliser int. Cela n'a pas de sens pour moi. J'ai vu des documents (comme celui du site officiel d'Apple) dire que long sont bien 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 et int conservent une longueur de 32 bits et de nouveaux types de données spéciaux sont définis pour les entiers 64 bits.

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

Que devrais-je utiliser? Devrais-je définir quelque chose comme uw, sw (largeur (non) signée) comme un long si ce n’est pas sous Windows, et sinon faire une vérification de la taille de la CPU cible?

130
user34537

Dans le monde Unix, quelques arrangements étaient possibles pour la taille des nombres entiers et des pointeurs pour les plates-formes 64 bits. ILP64 (en réalité, très peu d’exemples, Cray en est un exemple) et LP64 (pour presque tout le reste). Les acronymes sont "int, long, les pointeurs sont en 64 bits" et "long, les pointeurs sont en 64 bits".

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é au profit de LP64 (c’est-à-dire que presque tous les nouveaux venus ont utilisé le LP64, conformément aux recommandations du groupe Aspen; seuls les systèmes ayant une longue tradition d’exploitation en 64 bits utilisent schème). 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 système différent pour la transition vers 64 bits: LLP64 ("long long, les pointeurs sont en 64 bits"). Cela a le mérite de signifier que les logiciels 32 bits peuvent être recompilés sans modification. Il a le 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 64 bits. Il y a toujours eu une révision nécessaire; il s'agissait simplement d'un ensemble de révisions différent de celui nécessaire sur les plates-formes Unix.

Si vous concevez votre logiciel autour de noms de type entier indépendants de la plate-forme, utilisez probablement l'en-tête C99 <inttypes.h>, Qui, lorsque les types sont disponibles sur la plate-forme, fournit, en signature (répertorié) et non signé (non répertorié; préfixe avec u'):

  • int8_t - nombres entiers de 8 bits
  • int16_t - entiers 16 bits
  • int32_t - entiers 32 bits
  • int64_t - entiers 64 bits
  • uintptr_t - entiers non signés assez gros pour contenir des pointeurs
  • intmax_t - la plus grande taille de nombre entier sur la plate-forme (peut être supérieure à int64_t)

Vous pouvez ensuite coder votre application en utilisant ces types là où cela est important, en faisant très attention aux types de systèmes (qui peuvent être différents). Il existe un type intptr_t - un type entier signé pour conserver 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 valeurs uintptr_t (ptrdiff_t).

Mais, comme le souligne la question (incrédule), il existe différents systèmes pour la taille des types de données entiers sur des machines 64 bits. S'y habituer; le monde ne va pas changer.

244
Jonathan Leffler

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 ayant souffert de la pourriture du lien, je vous propose donc un autre lien qui peut pourrir.


Pour plus d'informations sur les types d'API Windows tels que 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 tels que WinDef.h. J'ai énuméré quelques types pertinents ici:

 Type | S/U | x86 | x64 
 ---------------------------- + ----- + -------- + ------- 
 BYTE, BOOLEAN | U | 8 bits | 8 bits 
 ---------------------------- + ----- + -------- + ------- 
 SHORT | S | 16 bits | 16 bits 
 USHORT, Word | U | 16 bits | 16 bits 
 ---------------------------- + ----- + -------- + ------- 
 INT, LONG | S | 32 bits | 32 bits 
 UINT, ULONG, DWORD | U | 32 bits | 32 bits 
 ---------------------------- + ----- + -------- + ------- 
 INT_PTR, LONG_PTR, LPARAM | S | 32 bits | 64 bits 
 UINT_PTR, ULONG_PTR, WPARAM | U | 32 bits | 64 bits 
 ---------------------------- + ----- + -------- + ------- 
 LONGLONG | S | 64 bits | 64 bits 
 ULONGLONG, QWORD | U | 64 bits | 64 bits 

La colonne "S/U" indique signé/non signé.

50
Martin Liversage

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

4
reuben

Microsoft a également défini UINT_PTR et INT_PTR pour des entiers de la même taille qu’un pointeur.

Voici un liste de types spécifiques à Microsoft - cela fait partie de leur référence de pilote, mais je pense que cela est également valable pour la programmation en général.

4
Mark Ransom

Le moyen le plus simple de le connaître pour votre compilateur/plateforme:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

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 laisser le système de configuration déterminer le bon type pour la taille requise.

2
Paul de Vrieze

Si vous devez 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.

0
PolyThinker