2011-09-30 19 views
14

He descargado MinGW-64, así que ahora puedo compilar programas de 64 bits para Windows 7, usando g ++ 4.7.0 (experimental). Pero la siguiente línea:sizeof (long) en 64 bits C++

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

impresiones 4 8, no 8 8. La documentación de g ++ 4.6.0 dice:

Los conjuntos entorno de 64 bits a 32 bits int y largo y el puntero de 64 bits

¿Alguien sabe por qué no es sizeof(long) 8?

Editado para agregar: La fuente de mi confusión fue que g ++ 4.7.0 para Windows de 64 bits no es (todavía) una parte oficial de la Colección de compiladores de GNU. Y es la primera versión de 64 bits con un long de 32 bits, por lo que la documentación simplemente no se aplica a ella. De hecho, si vas a la relevant web page, la entrada completa para IA-32/x86-64 consiste en esto:

...

+2

Parece alguien simplemente votó negativamente la mitad de las respuestas sin dejar ningún comentario ... – Mysticial

+0

@Mystical: ¡Y mi pregunta también! – TonyK

+0

Si necesita un entero de 64 bits use int64_t/uint64_t o defina el suyo. De esta forma, su código será portátil y no dependerá de los detalles de la plataforma para los tamaños int/long/short. – David

Respuesta

15

Porque no tiene que ser así. El estándar de C++ solo requiere que sea (si la memoria sirve) de al menos 32 bits de ancho, y al menos tan grande como int.

MSVC (y el ABI utilizado por Windows) define long a ser de 32 bits de ancho, y MingW hace lo mismo, porque así, el compilador es mucho más útil cuando se está de acuerdo con el sistema operativo anfitrión

+1

No estoy hablando del estándar C++, estoy hablando de la propia documentación de la Colección GNU Compiler. – TonyK

+4

Lo sé. Así que lea la primera oración en mi respuesta. Y el último. La documentación que encontraste solo (supongo) describe la ABI para Linux que se ejecuta en x64.No dice nada acerca de otras CPU (ARM, MIPS, Alpha, SPARC o lo que sea), y no dice nada sobre puertos a diferentes sistemas operativos. – jalf

11

En el sistema operativo Microsoft Windows que tiene por lo LLP64 el tamaño de largo es 32 bit. (Véase la tabla siguiente)

Cita de Wikipedia:

En programas de 32 bits, punteros y tipos de datos tales como números enteros en general tienen la misma longitud; esto no es necesariamente cierto en máquinas de 64 bits. La combinación de tipos de datos en lenguajes de programación como C y sus descendientes, como C++ y Objective-C, puede funcionar en implementaciones de 32 bits pero no en implementaciones de 64 bits. En muchos entornos de programación para lenguajes derivados de C y C en máquinas de 64 bits, las variables "int" aún tienen 32 bits de ancho, pero los enteros largos y los punteros tienen 64 bits de ancho. Se describe que tienen un modelo de datos LP64. Otra alternativa es el modelo de datos ILP64 en el que los tres tipos de datos tienen 64 bits de ancho, e incluso SILP64, donde los enteros "cortos" también tienen 64 bits de ancho. Sin embargo, en la mayoría de los casos, las modificaciones requeridas son relativamente menores y sencillas, y muchos programas bien redactados simplemente pueden recompilarse para el nuevo entorno sin cambios. Otra alternativa es el modelo LLP64, que mantiene la compatibilidad con el código de 32 bits al dejar int y long como 32 bits. "LL" se refiere al tipo "entero largo largo", que es de al menos 64 bits en todas las plataformas, incluidos los entornos de 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

Quizás un poco de explicación de lo que significa la tabla * *? ;) – jalf

+1

¿Qué tal un enlace de referencia? –

+0

Aquí se explican los diferentes modelos: http://en.wikipedia.org/wiki/64-bit –

0

Es específico del sistema operativo. Windows todavía tiene un tamaño de 32 bits largos

0

La mayor parte de las aplicaciones de Windows se escriben con la expectativa de que para todos los efectos int = long = 32 bits. Supongo que MinGW solo se asegura de que siga siendo así y de que no hay sorpresas.

2

MinGW está diseñado para compilar una aplicación WIN32 y las cabeceras/bibliotecas WIN32 suponen que el tipo largo (o LARGO) tiene 32 bits de ancho incluso en un Windows de 64 bits. Microsoft decidió que, de lo contrario, muchos de los códigos fuente de Windows deberían cambiarse. Por ejemplo, la siguiente estructura usa tipos LONG.

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

;

+0

'LONG' es solo una macro. Se puede cambiar fácilmente a 'int32_t', por lo que esta no es una razón válida. – rustyx

0

MinGW está diseñado para crear aplicaciones de Windows, y la plataforma de Microsoft ABI specifies tiene int y con el mismo tamaño de 32 bits. Si MinGW definió long de manera diferente a MSVC, la mayoría de las aplicaciones de Windows existentes que usan long se romperían cuando se compilaran utilizando MinGW.

Dicho esto, Cygwin x86_64 sigue la convención LP64 en Windows, al igual que en Linux (source).

Así se puede utiliza para compilar una aplicación de Windows en el que el tamaño de long es de 8 bytes :) casos

prueba:

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

compilar con: C:\cygwin64\bin\gcc.exe -mwindows -m64 cygwin-test.c -o cygwin-test

Salida:

Windows 64-bit LP64 using Cygwin

Cuestiones relacionadas