2011-09-30 4 views
14

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:sizeof (long) en 64 bits C++

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

impressions 4 8, non 8 8. La documentation de g ++ 4.6.0 dit:

Les ensembles d'environnement 64 bits à 32 bits int et long et pointeur sur 64 bits

Quelqu'un sait-il pourquoi sizeof(long) n'est pas 8? La source de ma confusion était que g ++ 4.7.0 pour Windows 64 bits n'est pas (encore) une partie officielle de la Collection de compilateurs GNU. Et c'est la première version 64 bits avec un long 32 bits, donc la documentation ne s'applique tout simplement pas. En effet, si vous allez à l'relevant web page, l'entrée complète pour IA-32/x86-64 se compose de ceci:

...

+2

On dirait Quelqu'un vient de réduire en série la moitié des réponses sans laisser de commentaires ... – Mysticial

+0

@Mystical: Et ma question aussi! – TonyK

+0

Si vous avez besoin d'un entier de 64 bits, utilisez int64_t/uint64_t ou définissez le vôtre. De cette façon, votre code sera portable et ne dépendra pas des spécificités de la plate-forme pour les tailles int/long/short. – David

Répondre

15

Parce que cela ne doit pas être. La norme C++ exige seulement qu'elle soit (si la mémoire le permet) d'au moins 32 bits de large, et au moins aussi grande que int.

MSVC (et l'ABI utilisé par Windows) définit long être 32 bits de large, et MingW emboîte le pas, car bien, le compilateur est beaucoup plus utile quand il est d'accord avec le système d'exploitation hôte

+1

Je ne parle pas de la norme C++, je parle de la propre documentation de la collection de compilateurs GNU. – TonyK

+4

Je sais. Alors lisez la première phrase de ma réponse. Et la dernière. La documentation que vous avez trouvée seulement (je suppose) décrit l'ABI pour Linux s'exécutant sur x64.Il ne dit rien sur les autres processeurs (ARM, MIPS, Alpha, SPARC ou quoi que ce soit d'autre), et il ne dit rien sur les ports à différents systèmes d'exploitation. – jalf

11

Sur le Microsoft Windows OS vous avez LLP64 si la taille de long est de 32 bits. (Voir le tableau ci-dessous)

Citation de wikipedia:

Dans les programmes 32 bits, les pointeurs et les types 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 dérivés de C et C sur des 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. Ils sont décrits 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 comme 32 bits. "LL" fait référence au type "long long integer", qui est d'au moins 64 bits sur toutes les plates-formes, 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 
+1

Peut-être un peu d'explication de ce que la table * signifie *? ;) – jalf

+1

Que diriez-vous d'un lien de référence? –

+0

Ici les différents modèles sont expliqués: http://en.wikipedia.org/wiki/64-bit –

0

C'est spécifique au système d'exploitation. Windows a toujours la taille de long 32 bits égaux

0

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

2

MinGW est conçu pour générer une application WIN32 et les en-têtes/bibliothèques WIN32 supposent que le type long (ou LONG) est de 32 bits, même sur un Windows 64 bits. Microsoft a décidé que sinon une grande partie des codes source Windows existants devraient être modifiés. Par exemple, la structure suivante utilise des types LONG.

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

;

+0

'LONG' est juste une macro. Il peut être facilement changé en 'int32_t', ce n'est donc pas une raison valable. – rustyx

0

MinGW est conçu pour construire des applications Windows, et la plate-forme Microsoft ABI specifies que int et long ont la même taille de 32 bits. Si MinGW a défini long différemment de MSVC, la plupart des applications Windows existantes qui utilisent long sont endommagées lors de la compilation à l'aide de MinGW. Cela dit, Cygwin x86_64 suit la convention LP64 sous Windows, tout comme sur Linux (source).

Ainsi, vous pouvez l'utiliser pour construire une application Windows où la taille de long est de 8 octets :)

cas d'essai:

#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; 
} 

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

Sortie:

Windows 64-bit LP64 using Cygwin