Der folgende Code gibt eine andere Ausgabe aus, wenn die Version in Visual Studio und die Version außerhalb von Visual Studio ausgeführt wird. Ich verwende Visual Studio 2008 und ziele auf .NET 3.5 ab. Ich habe auch .NET 3.5 SP1 ausprobiert.
Wenn Sie außerhalb von Visual Studio ausgeführt werden, sollte die JIT aktiviert werden. Entweder (a) mit C # ist etwas Feines los, das mir fehlt, oder (b) die JIT ist tatsächlich fehlerhaft. Ich bin mir nicht sicher, ob die GEG schief gehen kann, aber mir gehen andere Möglichkeiten aus ...
Ausgabe bei Ausführung in Visual Studio:
0 0,
0 1,
1 0,
1 1,
Ausgabe beim Ausführen einer Version außerhalb von Visual Studio:
0 2,
0 2,
1 2,
1 2,
Was ist der Grund?
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();
}
}
}
Antworten:
Es ist ein JIT-Optimierungsfehler. Es rollt die innere Schleife ab, aktualisiert aber den oVec.y-Wert nicht richtig:
Der Fehler verschwindet, wenn Sie oVec.y auf 4 erhöhen lassen. Das sind zu viele Aufrufe zum Abrollen.
Eine Problemumgehung ist folgende:
UPDATE: Im August 2012 erneut überprüft, wurde dieser Fehler in der Version 4.0.30319 Jitter behoben. Ist aber noch im v2.0.50727 Jitter vorhanden. Es ist unwahrscheinlich, dass sie dies nach so langer Zeit in der alten Version beheben werden.
quelle
Ich glaube, das ist ein echter JIT-Kompilierungsfehler. Ich würde es Microsoft melden und sehen, was sie sagen. Interessanterweise stellte ich fest, dass die x64-JIT nicht das gleiche Problem hat.
Hier ist meine Lektüre des x86 JIT.
Das sieht nach einer für mich schlechten Optimierung aus ...
quelle
Ich habe Ihren Code in eine neue Konsolen-App kopiert.
Es ist also die x86-JIT, die den Code falsch generiert. Habe meinen Originaltext über die Neuordnung von Schleifen usw. gelöscht. Einige andere Antworten hier haben bestätigt, dass die JIT die Schleife unter x86 falsch abwickelt.
Um das Problem zu beheben, können Sie die Deklaration von IntVec in eine Klasse ändern, die in allen Varianten funktioniert.
Denken Sie, dass dies auf MS Connect gehen muss ....
-1 an Microsoft!
quelle