2008-12-21 16 views
113

No hace mucho tiempo, alguien me dijo que 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) decir que long son de hecho 64 bits al compilar para una CPU de 64 bits. Levanté la vista de lo que era en Windows de 64 bits y encontré¿Cuál es el tamaño de bit de largo en Windows de 64 bits?

  • de Windows: long y int siguen siendo de 32 bits de longitud, y los nuevos tipos de datos especiales se definen para los 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 (ancho no firmado) como long si no está en Windows, y de lo contrario verifico el tamaño de bits de la CPU objetivo?

+0

En Windows con MSVC++ int y largo son 32 bits: https://msdn.microsoft.com/en-us/library/3b2e7499.aspx. Sin embargo, para permitir, p. vectores para almacenar más de 4G de elementos, size_t es de 64 bits. Entonces uno necesita usar int64_t en lugar de int para iterar, p. vectores que pueden contener más de 4G elementos. –

+0

En ** Cygwin ** ['sizeof (long) == 8', incluso en Windows] (http://stackoverflow.com/a/39207744/485343) :-) – rustyx

+0

@SergeRogatch deberían usar' size_t' o un tipo de iterador para iterar, no 'int' o' int64_t' –

Respuesta

0

Si necesita utilizar enteros de cierta longitud, probablemente deba usar encabezados independientes de la plataforma para ayudarlo. Boost es un buen lugar para mirar.

4

este artículo en MSDN hace referencia a un número de alias de tipo (disponible en Windows) que son un poco más explícita con respecto a su anchura:

http://msdn.microsoft.com/en-us/library/aa505945.aspx

Por ejemplo, aunque se puede utilizar ULONGLONG para hacer referencia 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?

+1

¿Hay alguna garantía de que uint32_t y DWORD serán intercambiables? No es difícil imaginar que tal vez no lo sean [p. si el primero es un 'int' de 32 bits y el último un' long' de 32 bits, gcc asumiría que un puntero a un tipo no podría alias el otro a pesar de sus representaciones coincidentes]. – supercat

2

La forma más fácil de llegar a conocer por su compilador/plataforma:

#include <iostream> 

int main() { 
    std::cout << sizeof(long)*8 << std::endl; 
} 

Themultiplication por 8 es conseguir que los 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.

+4

No es que importe, pero los bytes de 8 bits no son realmente parte de la especificación C (cláusula 3.6 y 5.2.4.2.1 del estándar C). Aunque sería difícil encontrar una máquina que no tuviera 8 bits, podría verificar LONG_BIT para ver qué tan grande es su largo tipo de datos. – Andres

+0

Por supuesto, tiene razón, en realidad depende de la arquitectura ("unidad de almacenamiento de datos direccionable lo suficientemente grande como para contener cualquier miembro del conjunto de caracteres básicos del entorno de ejecución"), pero las arquitecturas más comúnmente utilizadas equivalen a 8 bits. –

+0

Pero el OP no preguntó por * su * compilador/plataforma; preguntó específicamente acerca de Windows de 64 bits, presumiblemente porque * no * tiene un acceso conveniente a un sistema de Windows de 64 bits para probar. – Quuxplusone

3

Microsoft también ha definido UINT_PTR e INT_PTR para enteros que son del mismo tamaño que un puntero.

Aquí está un list of Microsoft specific types - es parte de su referencia de controlador, pero creo que es válido también para la programación general.

222

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 en favor de LP64 (es decir, los participantes casi todos los posteriores utilizados LP64, con base en las recomendaciones del grupo de Aspen, y sólo los sistemas con una larga tradición de funcionamiento de 64 bits utilizar una diferente esquema). 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, pointers are 64-bit'). 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 nombres de tipo entero de plataforma neutra, probablemente usando 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; prefijo con 'u'):

  • int8_t - números enteros de 8 bits
  • int16_t - enteros de 16 bits
  • int32_t - enteros de 32 bits
  • int64_t - 64 bits en tegers
  • uintptr_t - enteros sin signo suficientemente grande para contener punteros
  • intmax_t - mayor tamaño de número entero en la plataforma (podrían ser más grande que int64_t)

continuación, puede codificar su aplicación utilizando este tipo donde importa y ser muy cuidadoso 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 de uintptr_t (ptrdiff_t).

Pero, como la pregunta señala (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

+8

Para aquellos de uso que han estado presentes lo suficiente, la transición de 64 bits tiene algunos paralelismos con la transición de 16 bits a 32 bits de mediados de los 80. Había computadoras que eran IL32 y otras que eran L32 (adaptando la nueva notación al viejo problema). A veces 'int' era de 16 bits, a veces de 32 bits. –

+2

No olvide que esto solo se aplica a los idiomas C-ish. Otros tienen especificaciones más seguras donde a) el compilador no puede elegir el tamaño de los tipos de datos willi-nilly ob) la representación física de los tipos de datos no "gotea" oc) los enteros siempre son infinitamente grandes. –

+0

Es cierto, pero para los idiomas que especifican el comportamiento, no hay un problema en primer lugar. Por ejemplo, Java tiene un 'largo', pero el tamaño es fijo (¿64 bits?) En todas las plataformas. Por lo tanto, no hay problemas de migración a una máquina de 64 bits; el tamaño no cambia –

38

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 acerca de los tipos de API de Windows como INT, LONG etc. Hay una página en MSDN:

Windows Data Types

La información también está disponible en varios archivos de cabecera 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/no firmado.

+3

Tres años y medio después, y su enlace sigue siendo bueno – makoshichi

Cuestiones relacionadas