No hace mucho tiempo, alguien me dijo que long
no son 64 bits en máquinas de 64 bits y que siempre debería usar int
. Esto no tenía sentido para mí. He visto documentos (como el del sitio oficial de Apple) que dicen que en long
realidad son 64 bits al compilar una CPU de 64 bits. Miré qué era en Windows de 64 bits y encontré
- Windows:
long
yint
permanecen de 32 bits de longitud, y se definen 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é debo usar? ¿Debo definir algo como uw
, sw
((sin) ancho firmado) como long
si no en Windows, y de lo contrario hacer una verificación en el tamaño de bits de la CPU de destino?
sizeof(long) == 8
, incluso en Windows :-)size_t
o un tipo de iterador para iterar, noint
oint64_t
size_t
esto se vuelve complicado cerca de los números negativos, porquesize_t
no está firmado. Asífor(size_t i=0; i<v.size()-2; i++)
falla por tamaño del vector 0 y 1. Otro ejemplo:for(size_t i=v.size()-1; i>=0; i--)
.size_t
valores, entonces el resultado debe mantenerse en una variable deptrdiff_t
tipo, ¡que está diseñado para ser lo suficientemente grande como para contener dicho resultado y es un tipo con signo precisamente por esa razón!)Respuestas:
En el mundo de Unix, había algunos arreglos posibles para los tamaños de enteros y punteros para plataformas de 64 bits. Los dos más utilizados fueron ILP64 (en realidad, 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'.
El sistema ILP64 se abandonó a favor de LP64 (es decir, casi todos los participantes posteriores usaron LP64, según las recomendaciones del grupo Aspen; solo los sistemas con una larga herencia de operación de 64 bits usan un esquema diferente). Todos los sistemas Unix modernos de 64 bits usan LP64. MacOS X y Linux son sistemas modernos de 64 bits.
Microsoft usa un esquema diferente para la transición a 64 bits: LLP64 ('largo largo, los punteros son de 64 bits'). Esto tiene el mérito de significar que el software de 32 bits se puede volver a compilar sin cambios. Tiene el valor de ser diferente de lo que hacen los demás, y también requiere que se revise el código para explotar las capacidades de 64 bits. Siempre hubo una revisión necesaria; fue solo un conjunto diferente de revisiones de las necesarias en las plataformas Unix.
Si diseña su software alrededor de nombres de tipos enteros neutros en la plataforma, probablemente utilizando el
<inttypes.h>
encabezado C99 , que, cuando los tipos están disponibles en la plataforma, proporciona, con signo (listado) y sin signo (no listado; prefijo con 'u'):int8_t
- enteros de 8 bitsint16_t
- enteros de 16 bitsint32_t
- enteros de 32 bitsint64_t
- enteros de 64 bitsuintptr_t
- enteros sin signo lo suficientemente grandes como para contener punterosintmax_t
- mayor tamaño de entero en la plataforma (puede ser mayor queint64_t
)Luego puede codificar su aplicación utilizando estos tipos donde sea importante y teniendo mucho cuidado con los tipos de sistema (que pueden ser diferentes). Hay un
intptr_t
tipo: un tipo entero con signo para mantener punteros; debe planear no usarlo, o solo usarlo como resultado de una resta de dosuintptr_t
valores (ptrdiff_t
).Pero, como señala la pregunta (incrédulo), 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.
fuente
short
, ¿cómo llama al tipo de 16 bits? Y si llama al tipo de 16 bitschar
para UTF-16, etc., ¿cómo llama al tipo de 8 bits? Entonces, el uso de LP64 te deja con 8 bitschar
, 16 bitsshort
, 32 bitsint
, 64 bitslong
, con espacio para la expansión hacia arriba a 128 bitslong long
cuando (si?) Eso se vuelve relevante. Después de eso, tienes más potencias de 256 que nombres en C (bueno, supongo que podrías tener 256 bitsintmax_t
, y solo entonces te quedas sin). Hay mérito para LP64.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 la rotura del 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:Tipos de datos de Windows
La información también está disponible en varios archivos de encabezado de Windows como
WinDef.h
. He enumerado algunos tipos relevantes aquí:La columna "S / U" denota firmado / sin firmar.
fuente
Este artículo en MSDN hace referencia a una serie de 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 ocurre con ULONG y UINT32.) ¿Quizás estos serán un poco más claros?
fuente
int
y el segundo de 32 bitslong
, gcc supondría que un puntero a un tipo no podría alias al otro a pesar de sus representaciones coincidentes].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 la programación general.
fuente
La forma más fácil de conocerlo para su compilador / plataforma:
La multiplicación por 8 es obtener bits de bytes.
Cuando necesita 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.
fuente
El tamaño en bits de
long
en plataformas Windows es de 32 bits (4 bytes).Puede verificar esto usando
sizeof(long)
.fuente
Si necesita usar enteros de cierta longitud, probablemente debería usar algunos encabezados independientes de la plataforma para ayudarlo. Boost es un buen lugar para mirar.
fuente