¿Cuál es la diferencia entre size_t e int en C ++?

En varios ejemplos de C ++ veo un uso del tipo size_t donde habría usado un int simple. ¿Cuál es la diferencia, y por qué size_t debería ser mejor?

De la amistosa Wikipedia :

Los archivos de encabezado stdlib.h y stddef.h definen un tipo de datos llamado size_t que se usa para representar el tamaño de un objeto. Las funciones de biblioteca que toman tamaños esperan que sean del tipo size_t, y el tamaño del operador se evalúa como size_t.

El tipo real de size_t depende de la plataforma; un error común es suponer que size_t es lo mismo que unsigned int, lo que puede conducir a errores de progtwigción, particularmente a medida que las architectures de 64 bits se vuelven más frecuentes.

Además, verifique por qué size_t importa

size_t es el tipo utilizado para representar los tamaños (como lo implican sus nombres). Su plataforma (e incluso su implementación potencial) depende, y debe usarse solo para este propósito. Obviamente, representando un tamaño, size_t no tiene firma. Muchas funciones stdlib, incluyendo malloc, sizeof y varias funciones de operación de cadenas usan size_t como un tipo de datos.

Un int está firmado por defecto, y aunque su tamaño también depende de la plataforma, será un 32 bits fijo en la mayoría de las máquinas modernas (y aunque size_t es 64 bits en la architecture de 64 bits, int permanece 32 bits de largo en esas architectures).

Para resumir: use size_t para representar el tamaño de un objeto e int (o long) en otros casos.

Es porque size_t puede ser cualquier cosa que no sea int (tal vez una estructura). La idea es que desacopla su trabajo del tipo subyacente.

El tipo size_t se define como el tipo integral sin signo del operador sizeof . En el mundo real, a menudo verá int definido como 32 bits (para compatibilidad con versiones anteriores) pero size_t definido como 64 bits (para que pueda declarar matrices y estructuras de más de 4 GiB en tamaño) en plataformas de 64 bits. Si un long int también tiene 64 bits, esto se llama convención LP64; if long int tiene 32 bits, pero long long int y los punteros son 64 bits, eso es LLP64. También puede obtener el reverso, un progtwig que usa instrucciones de 64 bits para la velocidad, pero punteros de 32 bits para ahorrar memoria. Además, int está firmado y size_t no tiene firma.

Históricamente, existían otras plataformas donde las direcciones eran más anchas o más cortas que el tamaño nativo de int . De hecho, en los años 70 y principios de los 80, esto era más común que no: todos los populares microordenadores de 8 bits tenían registros de 8 bits y direcciones de 16 bits, y la transición entre 16 y 32 bits también producía muchas máquinas que tenían direcciones más amplias que sus registros. De vez en cuando todavía veo preguntas sobre Borland Turbo C para MS-DOS, cuyo modo de memoria enorme tenía direcciones de 20 bits almacenadas en 32 bits en una CPU de 16 bits (pero que podían soportar el conjunto de instrucciones de 32 bits del 80386); el Motorola 68000 tenía una ALU de 16 bits con registros y direcciones de 32 bits; había mainframes IBM con direcciones de 15 bits, 24 bits o 31 bits. También sigue viendo diferentes tamaños de ALU y bus de direcciones en los sistemas integrados.

Siempre que int sea ​​menor que size_t e intente almacenar el tamaño o el desplazamiento de un archivo u objeto muy grande en un unsigned int , existe la posibilidad de que se desborde y cause un error. Con un int , también existe la posibilidad de obtener un número negativo. Si int o unsigned int es más amplio, el progtwig se ejecutará correctamente pero perderá memoria.

Por lo general, debe usar el tipo correcto para el propósito si desea la portabilidad. Mucha gente recomendará que use matemática firmada en lugar de sin firmar (para evitar errores sutiles y desagradables como 1U < -3 ). Para ese propósito, la biblioteca estándar define ptrdiff_t en como el tipo firmado del resultado de restar un puntero de otro.

Dicho esto, una solución alternativa podría ser establecer límites: compruebe todas las direcciones y compensaciones frente a INT_MAX y 0 o INT_MIN según corresponda, y active las advertencias del comstackdor sobre la comparación de las cantidades firmadas y no firmadas en caso de que omita alguna. Siempre, siempre, siempre debes verificar tus accesos a la matriz para desbordamiento en C de todos modos.

La definición de SIZE_T se encuentra en: https://msdn.microsoft.com/en-us/library/cc441980.aspx y https://msdn.microsoft.com/en-us/library/cc230394.aspx

Pegando aquí la información requerida:

SIZE_T es un ULONG_PTR representa el número máximo de bytes a los que un puntero puede apuntar.

Este tipo se declara de la siguiente manera:

 typedef ULONG_PTR SIZE_T; 

Un ULONG_PTR es un tipo largo sin signo utilizado para la precisión del puntero. Se usa al convertir un puntero a un tipo largo para realizar la aritmética del puntero.

Este tipo se declara de la siguiente manera:

 typedef unsigned __int3264 ULONG_PTR;