web-dev-qa-db-fra.com

sizeof (long) en C++ 64 bits

J'ai téléchargé MinGW-64, donc je peux maintenant compiler des programmes 64 bits pour Windows 7, en utilisant g ++ 4.7.0 (expérimental). Mais la ligne suivante:

cout << sizeof(long) << " " << sizeof(void*) << endl ;

imprime 4 8, pas 8 8. La documentation de g ++ 4.6.0 dit:

L’environnement 64 bits définit int sur 32 bits et long et le pointeur sur 64 bits

Est-ce que quelqu'un sait pourquoi sizeof(long) n'est pas 8?

Édité pour ajouter: La source de ma confusion était que g ++ 4.7.0 pour Windows 64 bits n'était pas (encore) une partie officielle de la GNU Compiler Collection. Et c'est la première version 64 bits avec une long 32 bits, donc la documentation ne s'y applique tout simplement pas. En effet, si vous accédez à la page Web pertinente , l'entrée complète pour IA-32/x86-64 est la suivante:

...

16
TonyK

Parce que ce n'est pas obligé. La norme C++ exige seulement qu’elle ait (si la mémoire le permet) au moins 32 bits de large et au moins égale à int.

MSVC (et l'ABI utilisée par Windows) définit long comme ayant une largeur de 32 bits, et MingW lui emboîte le pas, car le compilateur est beaucoup plus utile lorsqu'il est compatible avec le système d'exploitation hôte.

17
jalf

Sur le système d’exploitation Microsoft Windows, vous avez LLP64, de sorte que la taille de long est de 32 bits. (voir le tableau ci-dessous)

Citation de Wikipédia:

Dans les programmes 32 bits, les types de pointeurs et de données tels que les entiers ont généralement la même longueur; ce n'est pas nécessairement vrai sur les machines 64 bits. Le mélange de types de données dans des langages de programmation tels que C et ses descendants tels que C++ et Objective-C peut donc fonctionner sur des implémentations 32 bits mais pas sur des implémentations 64 bits. . Dans de nombreux environnements de programmation pour les langages C et C dérivés de machines 64 bits, les variables "int" ont toujours une largeur de 32 bits, mais les entiers longs et les pointeurs ont une largeur de 64 bits. Celles-ci sont décrites comme ayant un modèle de données LP64. Une autre alternative est le modèle de données ILP64 dans lequel les trois types de données ont une largeur de 64 bits, et même SILP64 où les entiers "courts" ont également une largeur de 64 bits. Cependant, dans la plupart des cas, les modifications requises sont relativement mineures et simples. , et de nombreux programmes bien écrits peuvent simplement être recompilés pour le nouvel environnement sans modifications. Une autre alternative est le modèle LLP64, qui maintient la compatibilité avec le code 32 bits en laissant int et long 32 bits. "LL" fait référence au type "entier long long", qui est au moins de 64 bits sur toutes les plateformes, y compris les environnements 32 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
12
Roel Van Nyen

MinGW est conçu pour créer une application WIN32 et les en-têtes/bibliothèques WIN32 supposent que le type long (ou LONG) a une largeur de 32 bits, même sous Windows 64 bits. Microsoft a décidé que sinon, une grande partie des codes sources Windows existants devrait être changé. Par exemple, la structure suivante utilise les types LONG.

typedef struct tagBITMAPINFOHEADER { 
...
  LONG biWidth; 
  LONG biHeight; 
...
} BITMAPINFOHEADER

2
relent95

MinGW est conçu pour créer des applications Windows et la plate-forme Microsoft ABI spécifie que int et long ont la même taille de 32 bits. Si MinGW définit long différemment de MSVC, la plupart des applications Windows existantes qui utilisent long se briseraient lors de la compilation à l'aide de MinGW.

Cela dit, Cygwin x86_64 respecte la convention LP64 sous Windows, tout comme sous Linux ( source ).

Vous pouvez donc l'utiliser pour créer une application Windows où la taille de long est de 8 octets :)

Cas de test:

#include <stdio.h>
#include <windows.h>

int CALLBACK WinMain(HINSTANCE a, HINSTANCE b, LPSTR c, int d)
{
  char buf[100];
  snprintf(buf, sizeof(buf),
    "sizeof(int)=%d, sizeof(long)=%d, sizeof(long long)=%d\n",
     sizeof(int), sizeof(long), sizeof(long long));
  MessageBox(NULL, buf, "Cygwin Test", MB_OK);
  return 0;
}

Compiler avec: C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

Sortie:

 Windows 64-bit LP64 using Cygwin

1
rustyx

C'est spécifique à l'OS. Windows a toujours une taille égale à 32 bits

0
Andrey Atapin

La plupart des applications Windows sont écrites dans l'espoir qu'à toutes fins utiles, int = long = 32 bits. Je suppose que MinGW s'assure simplement que c'est toujours le cas et qu'il n'y a pas de surprises.

0
Alexey Frunze