¿Por qué se inventaron short, int y long en C?

16

Yo no puedo entender, ¿cuáles fueron los efectos exactos de la creación de la short, inty longlos tipos de datos en C?

La razón por la que pregunto es que no parece que sus tamaños estén limitados; podrían ser de cualquier tamaño, siempre que shortsean más pequeños que un int, por ejemplo.

¿En qué situaciones, entonces, debería usar un unsigned into unsigned long, por ejemplo, en lugar de un size_t, cuando hacerlo no ofrece ninguna esperanza de compatibilidad binaria?

(Si no conoce el tamaño, ¿cómo saber cuándo elegir cuál?)

usuario541686
fuente
2
Echa un vistazo<stdint.h>
BlackJack
1
@BlackJack: Jaja sí, en realidad sí, pero creo que mi pregunta es, ¿por qué no se definen todos esos tipos de forma nativa? ¿Es un problema de "retrospectiva es 20/20", o hubo una razón específica?
user541686
2
C estaba destinado a ser portátil y cercano al hardware subyacente. Había plataformas en las que el byte no tenía una longitud de 8 bits, pero aún se podía usar C. Ningún conjunto fijo de tipos de datos sería suficiente, ningún integere de tamaño fijo podría ser portátil.
SK-logic
@ SK-logic: ¿Ni siquiera si dijeron sizeof(short) == 2 * sizeof(char)o algo similar?
user541686
1
Hay plataformas donde sizeof(char) == sizeof(short), y tiene sentido. Desafortunadamente, no hay forma de especificar tipos de números integrales de esa manera que se ajusten a todas las plataformas posibles y existentes.
SK-logic

Respuestas:

12

Estaría definido por la arquitectura que estaba utilizando. En un chip Zilog z80 (chip integrado común) tendrían un tamaño único, mientras que podrían ser de un tamaño completamente diferente en un chipset x86. Sin embargo, los tamaños en sí mismos son proporciones fijas entre sí. Esencialmente, short y long no son tipos, pero califican para el tipo int. Las entradas cortas serán de un orden de magnitud menor que las int (regulares) y las entradas largas serán de un orden de magnitud mayor. Digamos que su Int está limitado a 4 bytes, el calificador corto lo limita a 4 bytes, aunque 2 bytes también es muy común y el calificador largo lo aumenta potencialmente a 8 bytes, aunque puede ser menor a 4 bytes. Tenga en cuenta que esto también está sujeto a la longitud de la palabra, por lo que en un sistema de 32 bits tendría un máximo de 4 bytes por int de todos modos, haciendo lo mismo que un int normal. Por lo tanto, Corto ≤ Int ≤ Largo.

Sin embargo, si lo vuelve a alargar, puede empujar el int a la siguiente celda para obtener 8 bytes completos de almacenamiento. Este es el tamaño de palabra para las máquinas de 64 bits, por lo que no tienen que preocuparse por esas cosas y solo usan la celda para entradas largas, lo que les permite estar en otro orden por encima de las entradas estándar, mientras que las entradas largas y largas realmente se vuelven poco.

En cuanto a cuál elegir, se reduce a algo por lo que los programadores de Java, por ejemplo, no tienen que preocuparse. "¿Cuál es tu arquitectura?" Dado que todo depende del tamaño de palabra de la memoria de la máquina en cuestión, debe comprenderlo por adelantado antes de decidir cuál usar. Luego, elige el tamaño razonable más pequeño para ahorrar tanta memoria como sea posible porque esa memoria se asignará tanto si usa todos los bits como si no. Por lo tanto, ahorra donde puede y elige pantalones cortos cuando puede e ints cuando no puede y si necesita algo más grande que las entradas regulares que da; alargarías según sea necesario hasta que alcances la palabra techo. Entonces necesitaría suministrar rutinas de números grandes o obtenerlas de una biblioteca.

C bien puede ser "ensamblaje portátil" pero aún debe conocer su hardware.

Ingeniero mundial
fuente
11
esto no está del todo bien, los pantalones cortos no tienen que ser más pequeños que los ints, no pueden ser más grandes que los ints
jk.
Lo corregiré.
Ingeniero mundial
2
Del mismo modo, los largos no pueden ser más pequeños que los int.
Donal Fellows
1
de hecho, creo que ha habido máquinas donde short, int y long son exactamente iguales.
jk.
6

Aunque hoy, un "byte" significa "8 bits", eso no siempre ha sido cierto. Las máquinas han utilizado fragmentos direccionables de 4 bits, 8 bits, 12 bits, 16 bits, 32 bits y 36 bits (y probablemente también algunos otros tamaños). Una de las intenciones de diseño de C era ser utilizable en máquinas con diferentes tamaños y configuraciones de memoria.

Creo que la intención del diseño era originalmente que cada tipo, además de intser la cosa más pequeña, pudiera manejar números de varios tamaños, y queint fuera el tamaño "de propósito general" más práctico que pudiera manejar +/- 32767. No creo que haya habido ningún deseo o intención de crear un lenguaje que todavía estuviera en uso cuando las computadoras se volvieran tan poderosas que las operaciones en números de 64 bits cuestan lo mismo que las operaciones en números más pequeños.

El mayor problema con la semántica de tipo entero de C es que en algunos contextos representan números cardinales o enteros matemáticos, mientras que en otros contextos se usan para representar miembros de un anillo algebraico abstracto envolvente de enteros congruentes mod 2 ^ n [por ejemplo, restando el valor máximo representable de 0 se define para producir 1], pero los comportamientos se especifican más en función de lo que los compiladores parecían hacer los días en que los tamaños de palabras de la computadora eran de alrededor de 16 bits (y un tamaño de palabra de 36 bits habría sido enorme ), en lugar de basarse en lo que tendría sentido en una máquina de 64 bits. En consecuencia, el resultado de restar un valor sin signo de 32 bits de un valor menor sin signo de 32 bits puede ser un valor grande sin signo de 32 bits o un número negativo de 64 bits.

Super gato
fuente
4

/programming/589575/size-of-int-long-etc

Entonces, en las arquitecturas más utilizadas, char tiene 1 byte, short e int tienen al menos 2 bytes y long tiene al menos 4 bytes.

Y se pretende que 'int' sea la representación más natural / normal / eficiente para la CPU actual.

Entonces, la regla general es usar 'int' a menos que sus valores excedan +/- 32K, lo que hace que usted (en CPU más antiguas) use 'largo'. ... o a menos que esté haciendo grandes matrices de valores pequeños (<32K), y la memoria es un problema, por lo que usaría 'short' para ahorrar memoria (o tal vez 'char' o 'byte').

Jeff Grigg
fuente
2
Pero con 64 bits, intcasi nunca es una buena opción, ¿verdad? Casi siempre termino usando size_t(¡o incluso ptrdiff_t!) De todos modos, para evitar problemas con el código de portabilidad.
user541686
@Merhdad - int solía ser la mejor opción, se definió como la 'unidad estándar' del HW y, por lo general, del tamaño de un puntero. Hoy en día use size_t por seguridad.
Martin Beckett
1

C fue diseñado para lidiar activamente con la memoria en diferentes niveles. Hay casos en los que la diferencia entre short, int y long, y entre float y double, importaba debido a restricciones de memoria, arquitectura, etc. Aunque ahora importa menos, todavía hay entornos en los que lo hace (por ejemplo, incrustado y en casos en los que los datos son masivos), y la transición de arquitecturas principalmente de 32 bits a 64 bits vuelve a ser un problema. (En diez o veinte años, cuando hagamos la transición a arquitecturas de 128 bits y C / C ++ siga siendo popular, volverá a ser un problema). Sin embargo, tiene razón en que la compatibilidad binaria sufre, por lo que no desea utilizar estos tamaños de tipo variable donde eso importa.

Preguntó cómo sabría qué usar si no conoce el tamaño, pero sí sabe el tamaño en una combinación dada de arquitectura / compilador, y si necesita optimizar la memoria a ese nivel, será mejor que lo sepa. No puede optimizarlo simplemente en todas las plataformas porque no puede conocer sus tamaños, por lo que no querría usar esas funciones para ese propósito. Pero muchas cosas escritas en C son específicas de la plataforma, lo que, a pesar de la moda de "plataforma cruzada", permite algunas optimizaciones ventajosas.

kylben
fuente