2009-12-21 6 views
5

Pregunta algo académica, pero: ¿cómo funcionan los tipos de valor como Int en realidad trabajo?¿Cómo funciona realmente un tipo de valor en .net?

He usado Reflector en mscorlib para descubrir cómo se implementa System.Int32, y es solo un Struct que hereda de System.ValueType. Estaba buscando algo entre las líneas de una matriz de bits que contenga el valor, pero solo encontré un campo que se declaró int, lo que significa que es una referencia circular.

Quiero decir, puedo escribir "int i = 14;", pero el número 14 necesita almacenarse en alguna parte de alguna manera, pero no pude encontrar la "Matriz de 32 bits" o un puntero o algo así.

¿Es esto algo mágico que hace el compilador, y estos tipos de magia son parte de la especificación? (Similar a cómo System.Attribute o System.Exception son tipos "especiales")

Edit: Si declaro mi propia estructura, le agrego campos. Esos campos son de tipo incorporado, por ejemplo int. Entonces el CLR sabe que tengo un int. ¿Pero cómo sabe que un int es 32 bits, firmado? ¿Es simplemente que la Especificación especifica ciertos tipos de base y, por lo tanto, los convierte en "magia", o hay un mecanismo técnico? Ejemplo hipotético: si quisiera declarar un Int36, que es un entero con 36 bits, ¿podría crear un tipo que funcione exactamente como un Int32 (aparte de los 4 bits extra de cc) al especificar "Bueno, dejar de lado 36 bits ", o son las primitivas incorporadas en piedra y tendría que trabajar de alguna manera alrededor de esto (es decir, mediante el uso de un Int64 y el código que solo establece los últimos 36 Bits)?

Como dije, todo muy académico e hipotético, pero siempre me pregunté sobre eso.

+0

Gran pregunta en realidad, me he preguntado qué soy yo. – Pierreten

+0

Yo también, esperaba que la pregunta fuera sobre cómo funcionan los tipos de valor, es decir, la pila frente al montón asignado, etc., pero tengo curiosidad sobre esto yo mismo. – Davy8

+1

Re a la edición: por lo que puedo decir, si quisiera crear un Int36, tendría que especificarlo de alguna manera en C# o IL, lo que le obligaría a usar un Int32 + Int8 o un Int64 con los últimos 28 bits ignorados o lo que sea. La única forma de agregar Int36 a la máquina virtual subyacente sin formato y hacer que comprenda la representación a nivel de bit sería implementar su propio CLR a la Mono o Rotor. – itowlson

Respuesta

3

Ciertos tipos primitivos, como los enteros, son parte de la especificación CLI. Por ejemplo, hay instrucciones de IL específicas como ldc.i4 para cargar valores de estos tipos, e instrucciones de IL como add tienen conocimiento específico de estos tipos. (Su ejemplo de int i = 14 conseguiría compilado a ldc.i4 14, con el 14 representan internamente como parte del código de operación dentro del MSIL compilado.)

Para obtener más información, consulte IIa partición del CLI spec, Sección 7.2, "Built-in Tipos " (No se puede encontrar un enlace a la sección en particular, lo siento). Los tipos incorporados son: bool, char, object, string, float32, float64, int [8 | 16 | 32 | 64], unsigned int [8 | 1632 | 64], native int (IntPtr), native unsigned int y typedref. La especificación señala que "tienen tipos de valores correspondientes definidos en la Biblioteca de clases base", lo que me hace pensar que Int32 es en realidad una especie de contenedor de metadatos alrededor del int32 "real", que vive en el nivel VES.

Otros tipos de valores, como System.Decimal, System.Drawing.Point o cualquiera de las estructuras que defina en su propio código, no son mágicos.

+0

Gracias. Entonces, en mi hipotético ejemplo de Int36, no tengo otra opción que usar un tipo incorporado (es decir, Int64 o bool [36]) y codificar el resto de mi tipo manualmente? –

+0

Correcto. Consulte el comentario "re your edit" en su pregunta. No tiene acceso al nivel de intercambio de bits a menos que implemente su propio CLR. – itowlson

1

Int32 es un compilador de tipo intrínseco, lo que significa que el compilador tiene una lógica especial para manejarlo. La implementación real de Int32 en el marco no tiene sentido.

Vale la pena señalar que Int16, Int32, UInt16, UInt32, Individual, Doble, etc. corresponden aproximadamente a los tipos que son nativos del conjunto de instrucciones x86 (y otros). Crear un tipo Int36 también requeriría usar un tipo nativo como base en el código de ensamblaje puro.

+0

Gracias. Sí, supongo que me encontraría con todo tipo de problemas de rendimiento de todos modos (alineación/relleno, que requieren 2 lecturas/escrituras en ia32, etc.). –

Cuestiones relacionadas