O que acontece nos bastidores quando você define um Int32 igual a um Int16?

votos
1

O que se passa em um nível baixo quando eu faço isso?

Int32 a = 0;
Int16 b = 50;

a = b;
Publicado 27/08/2009 em 06:32
fonte usuário
Em outras línguas...                            


3 respostas

votos
7

Algo assim:

IL_0001:  /* 1F   | 32               */ ldc.i4.s   50
IL_0003:  /* 0B   |                  */ stloc.1
IL_0004:  /* 07   |                  */ ldloc.1
IL_0005:  /* 0A   |                  */ stloc.0

Em um nível inferior, que depende da arquitetura da máquina e nível de otimização. Código como este, especificamente, que não tem nenhum efeito, provavelmente só irá ser omitida completamente. Caso contrário, vai ser código simples, talvez assim:

movsx eax, word ptr [ebp+12]
mov [ebp+8], eax

movsxé a instrução x86 que preserva o sinal de um número menor quando ele está sendo carregado em um destino maior; basicamente, ele examina o bit mais significativo da fonte menor e copia para os restantes bits quando é que se estende do número.

Respondeu 27/08/2009 em 06:38
fonte usuário

votos
2

De refletor:

.method public hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] int32 num,
        [1] int16 num2)
    L_0000: nop 
    L_0001: ldc.i4.0          ; Load the constant 0
    L_0002: stloc.0           ; Store the value into local var 0
    L_0003: ldc.i4.s 50       ; Load the constant 50 - notice it treats it as a 32-bit value
    L_0005: stloc.1           ; Store the value into local var 1
    L_0006: ldloc.1           ; Load local var 1
    L_0007: stloc.0           ; Store the value into local var 0
    L_0008: ret 
}

No nível IL, nada de especial acontece na atribuição, mas aviso de que ldc.i4.s 50trata o valor literal como um 4-byte inteiro (32-bit).

Quando o código é compilado JIT, o código de montagem resultando provavelmente apenas promove o valor 50 a um valor de largura de 32 bits.

Respondeu 27/08/2009 em 06:41
fonte usuário

votos
0

A pilha de avaliação não tem uma representação menor do que 32 bits. [Editar, na maioria dos casos (graças para a actualização do comentário :)] Até que você realmente armazenar um valor de 16 bits em algum lugar diferente da pilha, nada de especial acontece porque a shorte intsão do mesmo tamanho. Aqui são as únicas operações em que você veria uma diferença:

  • b = (short)a
    Vai assinar-se estendem de 16 bits do resultado a uma variável de largura de 32 bits completo. Esta é a conv.i4instrução mencionado no comentário.
  • *(short*)c = b ou cessão a um membro struct onde a estrutura é marcado StructLayout.Explicitou tem uma embalagem inferior a 4.
    Só vai escrever os 16 bits mais baixos de sua representação de 32 bits.
  • checked { b = (short)a; }
    Vai lançar uma exceção se (a < -32768 || a > 32767).
Respondeu 27/08/2009 em 07:07
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more