Sie haben einen Fehler bei der Codegenerierung im .NET 4 x86-Jitter gefunden. Es ist sehr ungewöhnlich und schlägt nur fehl, wenn der Code nicht optimiert ist. Der Maschinencode sieht folgendermaßen aus:
State a = s[0, 0];
013F04A9 push 0 ; index 2 = 0
013F04AB mov ecx,dword ptr [ebp-40h] ; s[] reference
013F04AE xor edx,edx ; index 1 = 0
013F04B0 call 013F0058 ; eax = s[0, 0]
013F04B5 mov dword ptr [ebp-4Ch],eax ; $temp1 = eax
013F04B8 movsx eax,byte ptr [ebp-4Ch] ; convert sbyte to int
013F04BC mov dword ptr [ebp-44h],eax ; a = s[0, 0]
Console.WriteLine(a == s[0, 0]); // False
013F04BF mov eax,dword ptr [ebp-44h] ; a
013F04C2 mov dword ptr [ebp-50h],eax ; $temp2 = a
013F04C5 push 0 ; index 2 = 0
013F04C7 mov ecx,dword ptr [ebp-40h] ; s[] reference
013F04CA xor edx,edx ; index 1 = 0
013F04CC call 013F0058 ; eax = s[0, 0]
013F04D1 mov dword ptr [ebp-54h],eax ; $temp3 = eax
; <=== Bug here!
013F04D4 mov eax,dword ptr [ebp-50h] ; a == s[0, 0]
013F04D7 cmp eax,dword ptr [ebp-54h]
013F04DA sete cl
013F04DD movzx ecx,cl
013F04E0 call 731C28F4
Eine Trottel-Affäre mit vielen temporären und Code-Duplikationen, die für nicht optimierten Code normal ist. Bemerkenswert ist der Befehl bei 013F04B8, bei dem die notwendige Umwandlung von sbyte in eine 32-Bit-Ganzzahl erfolgt. Die Array-Getter-Hilfsfunktion hat 0x0000000FF zurückgegeben, was State.BUG entspricht. Diese Funktion muss in -1 (0xFFFFFFFF) konvertiert werden, bevor der Wert verglichen werden kann. Der MOVSX-Befehl ist ein Sign eXtension-Befehl.
Dasselbe passiert erneut bei 013F04CC, aber dieses Mal gibt es keine MOVSX-Anweisung, um dieselbe Konvertierung durchzuführen. Dort fallen die Chips herunter, der CMP-Befehl vergleicht 0xFFFFFFFF mit 0x000000FF und das ist falsch. Dies ist also ein Auslassungsfehler. Der Codegenerator konnte MOVSX nicht erneut ausgeben, um dieselbe Konvertierung von Sbyte in Int durchzuführen.
Was an diesem Fehler besonders ungewöhnlich ist, ist, dass dies korrekt funktioniert, wenn Sie das Optimierungsprogramm aktivieren. Es kann jetzt in beiden Fällen MOVSX verwenden.
Der wahrscheinliche Grund, warum dieser Fehler so lange unentdeckt blieb, ist die Verwendung von sbyte als Basistyp der Aufzählung. Sehr selten zu tun. Die Verwendung eines mehrdimensionalen Arrays ist ebenfalls von entscheidender Bedeutung. Die Kombination ist fatal.
Ansonsten ein ziemlich kritischer Fehler, würde ich sagen. Wie weit verbreitet es sein könnte, ist schwer zu erraten. Ich muss nur den Jitter 4.6.1 x86 testen. Der x64- und der 3.5 x86-Jitter erzeugen sehr unterschiedlichen Code und vermeiden diesen Fehler. Die vorübergehende Problemumgehung, um fortzufahren, besteht darin, sbyte als Enum-Basistyp zu entfernen und es als Standard int zu lassen , sodass keine Vorzeichenerweiterung erforderlich ist.
Sie können den Fehler unter connect.microsoft.com einreichen. Die Verknüpfung mit diesen Fragen und Antworten sollte ausreichen, um ihnen alles zu sagen, was sie wissen müssen. Lassen Sie mich wissen, wenn Sie sich nicht die Zeit nehmen möchten, und ich werde mich darum kümmern.