Mamy następujące metody w klasie w jednym z naszych projektów:Kompilacja pomija kod po stałych bloków w niektórych metod
private unsafe void SomeMethod()
{
// Beginning of the method omitted for brevity
var nv = new Vector4[x];
fixed (Vector4* vp = nv)
{
fixed (float* tp = /* Source float ptr */)
{
fixed (double* ap = /* Source double ptr */)
{
for (var i = atlArray.Length - 1; i >= 0; --i)
{
vp[((i + 1) << 3) - 2] = new Vector4(tp[i], btt, 0.0f, 1.0f);
// Additional Vector4 construction omitted for brevity
nttp[i] = new Vector2(tp[i], this.ttvp);
nts[i] = string.Format(ap[i], /* etc. */);
}
}
}
}
this.ts = nts;
this.ttp = nttp;
this.V = nv; // <- This is a property setter
}
miałem do zaciemniać tego, ale mam nadzieję, że to wciąż wystarczająco jasne, aby uzyskać pomysł na to, co się dzieje.
Na jednej z maszyn naszych programistów, w kompilacjach debugujących kompilator C# usuwa trzy przypisania, które występują po zamknięciu bloku fixed
. Jeśli spróbujemy umieścić punkt przerwania na tych liniach, punkt przerwania przeskakuje do końcowego nawiasu metody po uruchomieniu aplikacji. Kod, który pojawia się między blokiem fixed
a końcem metody, jest usuwany również w innych metodach, ale nie jest to zagadkowe.
Po kilku eksperymentach okazało się, że włączenie w optymalizacji dla danego projektu spowodowało, że brakujący kod został uwzględniony. Jednak takie obejście się nie udaje w przypadku naszych testów jednostkowych - brakuje kodu, a zmiana optymalizacji projektu, którego dotyczy problem, i jego projektu testowego nie pomaga. Odkryliśmy również, że przeniesienie trzech przypisań wewnątrz najbardziej wewnętrznej instrukcji fixed
zadziałało - staje się jasne, dlaczego podczas badania IL.
W DLL debugowania zbudowany na maszynie dotkniętego (z optymalizacji wyłączony), A op powrót pojawia się bezpośrednio po ap
jest zdejmowana ze stosu:
IL_03a1: nop
IL_03a2: ldc.i4.0
IL_03a3: conv.u
IL_03a4: stloc.s ap
IL_03a6: ret
To wyjaśnia, dlaczego porusza trzy zadania przed stloc
instrukcja działa. W DLL debugowania zbudowany na moim komputerze, op powrót następuje w oczekiwanym miejscu, po trzech zadań:
IL_03a5: nop
IL_03a6: ldc.i4.0
IL_03a7: conv.u
IL_03a8: stloc.s ap
IL_03aa: nop
IL_03ab: ldc.i4.0
IL_03ac: conv.u
IL_03ad: stloc.s tp
IL_03af: nop
IL_03b0: ldc.i4.0
IL_03b1: conv.u
IL_03b2: stloc.s vp
IL_03b4: ldarg.0
IL_03b5: ldloc.s nts
IL_03b7: stfld string[] N.B.E.B::ts
IL_03bc: ldarg.0
IL_03bd: ldloc.s nttp
IL_03bf: stfld valuetype [SharpDX]SharpDX.Vector2[] N.B.E.B::ttp
IL_03c4: ldarg.0
IL_03c5: ldloc.s nv
IL_03c7: call instance void N.B.E.B::set_V(valuetype [SharpDX]SharpDX.Vector4[])
IL_03cc: nop
IL_03cd: ret
Mamy do tej pory nie udało się wytworzyć SSCCE - to zdaje się przejawiać jedynie w bardzo szczególnych okolicznościach i tylko w jednym z naszych projektów. Sprawdziliśmy, że na obu komputerach są używane te same wersje Visual Studio, platformy .NET, kompilatora C# i MSBuild. Sprawdziliśmy inne potencjalne różnice, takie jak wersja OS i aktualizacje. Rzeczy wyglądają tak samo na obu maszynach (są to te same modele laptopów). Jesteśmy trochę zaskoczeni, szczerze mówiąc. Każda pomoc byłaby bardzo cenna.
Czy to nie kompilator Roslyn? Mam to w C: \ Users \ Svick \ AppData \ Local \ Microsoft \ VisualStudio \ 12.0 \ Extensions \ 2wcdsxyh.slm \ rcsc.exe. Jeśli tak jest, możesz [zgłosić ten błąd zespołowi Roslyn] (https://roslyn.codeplex.com/WorkItem/Create). – svick
@svick To interesujący trop - dowiem się od mojego kolegi w poniedziałek, czy kiedykolwiek zainstalował kompilator Roslyn, i zgłosił ten problem zespołowi Roslyn, jeśli to zrobił. Odpowiem z powrotem. –