O código a seguir fornece uma saída diferente ao executar a versão dentro do Visual Studio e ao exterior do Visual Studio. Estou usando o Visual Studio 2008 e direcionando o .NET 3.5. Eu também tentei o .NET 3.5 SP1.
Quando executado fora do Visual Studio, o JIT deve entrar em ação. (A) há algo sutil acontecendo com o C # que estou ausente ou (b) o JIT está realmente com erro. Duvido que o JIT possa dar errado, mas estou ficando sem outras possibilidades ...
Saída ao executar dentro do Visual Studio:
0 0,
0 1,
1 0,
1 1,
Saída ao executar a versão fora do Visual Studio:
0 2,
0 2,
1 2,
1 2,
Qual é a razão?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
struct IntVec
{
public int x;
public int y;
}
interface IDoSomething
{
void Do(IntVec o);
}
class DoSomething : IDoSomething
{
public void Do(IntVec o)
{
Console.WriteLine(o.x.ToString() + " " + o.y.ToString()+",");
}
}
class Program
{
static void Test(IDoSomething oDoesSomething)
{
IntVec oVec = new IntVec();
for (oVec.x = 0; oVec.x < 2; oVec.x++)
{
for (oVec.y = 0; oVec.y < 2; oVec.y++)
{
oDoesSomething.Do(oVec);
}
}
}
static void Main(string[] args)
{
Test(new DoSomething());
Console.ReadLine();
}
}
}
Respostas:
É um bug do otimizador JIT. Ele está desenrolando o loop interno, mas não atualizando o valor oVec.y corretamente:
O bug desaparece quando você deixa oVec.y aumentar para 4, são muitas chamadas para desenrolar.
Uma solução alternativa é esta:
UPDATE: verificado novamente em agosto de 2012, esse bug foi corrigido no jitter da versão 4.0.30319. Mas ainda está presente no jitter da v2.0.50727. Parece improvável que eles consertem isso na versão antiga depois de tanto tempo.
fonte
Eu acredito que isso esteja ocorrendo em um bug de compilação JIT genuíno. Eu reportaria à Microsoft e veria o que eles dizem. Curiosamente, descobri que o x64 JIT não tem o mesmo problema.
Aqui está minha leitura do x86 JIT.
Parece uma otimização ruim para mim ...
fonte
Copiei seu código em um novo aplicativo de console.
Portanto, é o xIT JIT que gera incorretamente o código. Excluí meu texto original sobre a reordenação de loops etc. Algumas outras respostas aqui confirmaram que o JIT está desenrolando o loop incorretamente quando está no x86.
Para corrigir o problema, você pode alterar a declaração do IntVec para uma classe e funciona em todos os tipos.
Acho que isso precisa continuar no MS Connect ....
-1 para a Microsoft!
fonte