c++ - que - sistemas operativos de 32 y 64 bits
¿Cuál es el tamaño de bit de largo en Windows de 64 bits? (6)
No hace mucho tiempo, alguien me dijo que por long
no son 64 bits en máquinas de 64 bits y siempre debería usar int
. Esto no tiene sentido para mí. He visto documentos (como el del sitio oficial de Apple) que dicen que en realidad son 64 bits cuando se compila para una CPU de 64 bits. Busqué lo que era en Windows de 64 bits y encontré
- Windows:
long
eint
longitud de 32 bits y se han definido nuevos tipos de datos especiales para enteros de 64 bits.
(de http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )
¿Qué debería usar? ¿Debo definir algo como uw
, sw
(ancho de (sin) firma) como un long
si no en Windows, y de lo contrario verifico el tamaño de bits de la CPU objetivo?
En el mundo de Unix, hubo algunos arreglos posibles para los tamaños de enteros y punteros para plataformas de 64 bits. Los dos más ampliamente utilizados fueron ILP64 (de hecho, solo unos pocos ejemplos de esto; Cray fue uno de ellos) y LP64 (para casi todo lo demás). Los acrónimos provienen de ''int, long, los punteros son de 64 bits'' y ''long, los punteros son de 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
El sistema ILP64 fue abandonado a favor de LP64 (es decir, casi todos los participantes posteriores usaron LP64, según las recomendaciones del grupo Aspen, solo los sistemas con un largo historial de funcionamiento de 64 bits usan un esquema diferente). Todos los sistemas Unix de 64 bits modernos usan LP64. MacOS X y Linux son ambos sistemas modernos de 64 bits.
Microsoft usa un esquema diferente para la transición a 64 bits: LLP64 (''long long, punteros son 64 bits''). Esto tiene el mérito de significar que el software de 32 bits puede recompilarse sin cambios. Tiene el inconveniente de ser diferente de lo que hacen los demás, y también requiere que se revise el código para aprovechar las capacidades de 64 bits. Siempre hubo una revisión necesaria; era solo un conjunto diferente de revisiones de las que se necesitaban en las plataformas de Unix.
Si diseña su software alrededor de los nombres de tipo entero de plataforma neutra, probablemente utilizando el encabezado C99 <inttypes.h>
, que, cuando los tipos están disponibles en la plataforma, proporciona, en firmado (en la lista) y sin signo (no incluido en la lista; prefijo con ''u''):
-
int8_t
- enteros de 8 bits -
int16_t
- enteros de 16 bits -
int32_t
- enteros de 32 bits -
int64_t
- enteros de 64 bits -
uintptr_t
- enteros sin signo lo suficientemente grandes como para contener punteros -
intmax_t
: mayor tamaño del número entero en la plataforma (podría ser mayor queint64_t
)
A continuación, puede codificar su aplicación utilizando estos tipos donde sea importante y tener mucho cuidado con los tipos de sistema (que pueden ser diferentes). Hay un tipo intptr_t
: un tipo de entero con signo para contener punteros; debe planear no usarlo, o solo usarlo como resultado de una resta de dos valores ptrdiff_t
( ptrdiff_t
).
Pero, como señala la pregunta (con incredulidad), existen diferentes sistemas para los tamaños de los tipos de datos enteros en máquinas de 64 bits. Acostumbrarse a él; el mundo no va a cambiar
Este artículo en MSDN hace referencia a varios alias de tipo (disponibles en Windows) que son un poco más explícitos con respecto a su ancho:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Por ejemplo, aunque puede usar ULONGLONG para hacer referencia a un valor integral sin signo de 64 bits, también puede usar UINT64. (Lo mismo vale para ULONG y UINT32.) ¿Quizás esto será un poco más claro?
La forma más fácil de conocerlo para su compilador / plataforma:
#include <iostream>
int main() {
std::cout << sizeof(long)*8 << std::endl;
}
La multiplicación por 8 es obtener bits de bytes.
Cuando necesite un tamaño particular, a menudo es más fácil usar uno de los tipos predefinidos de una biblioteca. Si eso no es deseable, puede hacer lo que sucede a menudo con el software de autoconf y hacer que el sistema de configuración determine el tipo correcto para el tamaño necesario.
Microsoft también ha definido UINT_PTR e INT_PTR para enteros que son del mismo tamaño que un puntero.
Aquí hay una lista de tipos específicos de Microsoft : es parte de su referencia de controlador, pero creo que también es válida para programación general.
No está claro si la pregunta es sobre el compilador de Microsoft C ++ o la API de Windows. Sin embargo, no hay una etiqueta [c ++], así que supongo que se trata de la API de Windows. Algunas de las respuestas han sufrido de rotura de enlace, por lo que estoy proporcionando otro enlace que puede pudrirse.
Para obtener información sobre los tipos de API de Windows como INT
, LONG
, etc., hay una página en MSDN:
La información también está disponible en varios archivos de encabezado de Windows como WinDef.h
. He enumerado algunos tipos relevantes aquí:
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 columna "S / U" indica que está firmado / sin firmar.
Si necesita usar enteros de cierta longitud, probablemente deba usar encabezados independientes de la plataforma para ayudarlo. Boost es un buen lugar para mirar.