2011-12-24 22 views
39

Puesto que C# soporta Int8, Int16, Int32 y Int64, ¿por qué los diseñadores de la lengua eligen para definir int como un alias para Int32 en lugar de permitir que varíe en función de lo que la arquitectura nativa considera una word?En C#, ¿por qué "int" es un alias para System.Int32?

No he tenido ninguna necesidad específica de int para comportarme de manera diferente a como lo hace, solo estoy pidiendo por puro interés enciclopédico.

Creo que podría existir una arquitectura RISC de 64 bits que sería la más eficaz para admitir únicamente cantidades de 64 bits, y en la que las manipulaciones de cantidades de 32 bits requerirían operaciones adicionales. Tal arquitectura estaría en desventaja en un mundo en el que los programas insisten en usar enteros de 32 bits, que es otra forma de decir que C#, convirtiéndose en el lenguaje del futuro y todo, esencialmente impide que los diseñadores de hardware encuentren tales una arquitectura en el futuro.

StackOverflow no fomenta las respuestas especulativas, por lo que le pedimos que responda solo si su información proviene de una fuente confiable. Me he dado cuenta de que algunos miembros de SO son expertos de Microsoft, así que esperaba que pudieran darnos información sobre este tema.

Nota 1: lo hice, de hecho, lea todas las respuestas y todos los comentarios de SO: Is it safe to assume an int will always be 32 bits in C#?, pero no encontró ninguna pista sobre la razón por la que yo estoy pidiendo en esta pregunta.

Nota 2: la viabilidad de esta cuestión en el SO es decir (sin resultados) discutió aquí: Meta: Can I ask a “why did they do it this way” type of question?

+4

Si desea un "tipo de tamaño de máquina-palabra", está buscando 'System.IntPtr'. –

+0

Sí, pero tendemos a hacer aritmética con 'int's, no con' IntPtr's. –

+7

¿Por qué los votos a favor? – gdoron

Respuesta

33

Creo que la razón principal era la portabilidad de los programas dirigidos a CLR. Si permitieran que un tipo tan básico como int dependiera de la plataforma, hacer programas portátiles para CLR sería mucho más difícil. La proliferación de typedef -ed tipos integrales en código C/C++ de plataforma neutral para cubrir el uso de int incorporado es una indirecta de por qué los diseñadores de CLR decidieron hacer que los tipos incorporados sean independientes de la plataforma. Las discrepancias de este tipo son un gran inhibidor del objetivo de "escribir una vez, ejecutar en cualquier lugar" de los sistemas de ejecución basados ​​en máquinas virtuales.

Editar Más a menudo que no, el tamaño de un int obras de teatro en su código de forma implícita a través de operaciones de bits, en lugar de a través de la aritmética (después de todo, ¿qué podría salir mal con el i++, ¿verdad?) Pero los errores son generalmente más sutil. Considere un ejemplo a continuación:

const int MaxItem = 20; 
var item = new MyItem[MaxItem]; 
for (int mask = 1 ; mask != (1<<MaxItem) ; mask++) { 
    var combination = new HashSet<MyItem>(); 
    for (int i = 0 ; i != MaxItem ; i++) { 
     if ((mask & (1<<i)) != 0) { 
      combination.Add(item[i]); 
     } 
    } 
    ProcessCombination(combination); 
} 

Este código calcula y procesa todas las combinaciones de 20 elementos. Como puede ver, el código falla miserablemente en un sistema con 16 bits int, pero funciona bien con entradas de 32 o 64 bits.

El código no seguro proporcionaría otra fuente de dolor de cabeza: cuando el int se fija en un código de cierto tamaño (por ejemplo, 32) que asigna 4 veces el número de bytes como el número de entradas que necesita para funcionar, aunque es técnicamente incorrecto usar 4 en lugar de sizeof(int). ¡Además, este código técnicamente incorrecto sería portátil!

En última instancia, las cosas pequeñas como esa desempeñan un papel importante en la percepción de la plataforma como "buena" o "mala". Usuarios de.A los programas NET no les importa que un programa falle porque su programador cometió un error no portátil, o el CLR tiene fallas. Esto es similar a la forma en que los primeros Windows se percibían como no estables debido a la mala calidad de los conductores. Para la mayoría de los usuarios, un bloqueo es simplemente otro bloqueo del programa .NET, no un problema para los programadores. Por lo tanto, es bueno para la percepción del "ecosistema .NET" para hacer que el estándar sea tan indulgente como sea posible.

+0

Bueno, estoy seguro de que, al final, de alguna manera se reduce a la portabilidad, pero no veo exactamente cómo. Como ve, rara vez realizamos operaciones aritméticas cuyo resultado realmente depende de la longitud de bits específica de nuestros operandos, y para aquellos casos excepcionales en los que realmente realizamos tales operaciones, el lenguaje ya nos proporciona un prefecto perfecto Int8, Int16, Int32, Int64 y sus versiones sin firmar. –

+0

Además, el compilador/JIT podría proporcionarnos fácilmente versiones compiladas de forma diferente de nuestro programa para tamaño de palabra de máquina de 4 bytes y tamaño de palabra de máquina de 8 bytes, para que podamos probarlo en ambos escenarios en una sola máquina de desarrollo. –

+0

@MikeNakis Parece una buena suposición, excepto que se rompe si codifica 64 bits, y luego intenta ejecutar en 32 bits, las suposiciones sobre el entero mínimo y máximo pueden hacer que su código se rompa. También puede romper el código personalizado escrito para analizar/formatear enteros como cadenas. Recuerde que la idea de estos entornos tiene una portabilidad más garantizada que cualquier otra cosa. –

6

Muchos programadores tienen la tendencia a escribir código para la plataforma que utilizan. Esto incluye suposiciones sobre el tamaño de un tipo. Hay muchos programas C alrededor de los cuales fallará si el tamaño de un int se cambiara a 16 o 64 bits porque se escribieron bajo la suposición de que un int es de 32 bits. La elección de C# evita ese problema simplemente definiéndolo como eso. Si defines int como variable dependiendo de la plataforma, volverás al mismo problema. Aunque podría argumentar que es culpa de los programadores hacer suposiciones erróneas, hace que el lenguaje sea un poco más robusto (OMI). Y para las plataformas de escritorio, una int de 32 bits es probablemente la ocurrencia más común. Además, hace que transportar el código C nativo a C# sea un poco más fácil.

Editar: Creo que escribes código que hace suposiciones (implícitas) sobre el tamaño de un tipo con más frecuencia de la que crees. Básicamente, cualquier cosa que implique serialización (como .NET remoting, WCF, serialización de datos en el disco, etc.) le ocasionará problemas si permite tamaños de variables para int a menos que el programador se encargue del tipo de tamaño específico como int32. Y luego terminas con "usaremos int32 siempre de todos modos por si acaso" y no has ganado nada.

+0

Por favor vea mi primer comentario a @ dasblinkenlight's answer. –

+0

@MikeNakis: actualicé mi respuesta – ChrisWue

+0

Incluso la serialización a/desde un medio binario podría resolverse mediante atributos, así que, por ejemplo, podría declarar 'i' como un int nativo, y podría adjuntarle un atributo indicando que debe ser serializado como una pequeña cantidad endian de 32 bits. Pero en cualquier caso, veo el mérito en la última parte de lo que dijiste, que "terminas con 'usaremos int32 siempre de todos modos por si acaso' y no has ganado nada". Entonces, la conclusión es, me pregunto si Microsoft realizó algún tipo de investigación y determinó que esto inevitablemente terminaría siendo el caso. –

Cuestiones relacionadas