El siguiente código proporciona un resultado diferente cuando se ejecuta la versión dentro de Visual Studio y se ejecuta fuera de Visual Studio. Estoy usando Visual Studio 2008 y apunto a .NET 3.5. También probé .NET 3.5 SP1.
Cuando se ejecuta fuera de Visual Studio, el JIT debería funcionar. O (a) está sucediendo algo sutil con C # que me falta o (b) el JIT está realmente en error. Dudo que el JIT pueda salir mal, pero me estoy quedando sin otras posibilidades ...
Salida cuando se ejecuta dentro de Visual Studio:
0 0,
0 1,
1 0,
1 1,
Salida al ejecutar la versión fuera de Visual Studio:
0 2,
0 2,
1 2,
1 2,
¿Cuál es la razón?
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();
}
}
}
Respuestas:
Es un error del optimizador JIT. Desenrolla el bucle interno pero no actualiza el valor oVec.y correctamente:
El error desaparece cuando dejas que oVec.y se incremente a 4, son demasiadas llamadas para desenrollar.
Una solución es esta:
ACTUALIZACIÓN: revisado en agosto de 2012, este error se corrigió en la versión 4.0.30319 jitter. Pero aún está presente en la v2.0.50727 jitter. Parece poco probable que solucionen esto en la versión anterior después de tanto tiempo.
fuente
Creo que esto está en un error de compilación JIT genuino. Lo informaría a Microsoft y vería lo que dicen. Curiosamente, descubrí que el x64 JIT no tiene el mismo problema.
Aquí está mi lectura del x86 JIT.
Esto parece una optimización que me salió mal ...
fuente
Copié tu código en una nueva aplicación de consola.
Entonces, es el JIT x86 que genera incorrectamente el código. He eliminado mi texto original sobre la reordenación de bucles, etc. Algunas otras respuestas aquí han confirmado que el JIT está desenrollando el bucle incorrectamente cuando está en x86.
Para solucionar el problema, puede cambiar la declaración de IntVec a una clase y funciona en todos los sabores.
Creo que esto debe ir en MS Connect ...
-1 a Microsoft!
fuente