2014-09-08 7 views
6

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.

Odpowiedz

0

Mój kolega, programista, którego maszyna to dotyczy, znalazł różnicę w wynikach diagnostyki z kompilacji - był to kompilator C#. Pomyśleliśmy, że MSBuild używał pliku csc.exe w oczekiwanej lokalizacji (c: \ Program Files (x86) \ MSBuild \ 12.0 \ Bin), ale co dziwne, faktycznie wykonał csc.exe w C: \ Users \ [użytkownik] \ AppData \ Local \ Microsoft \ VisualStudio \ 12.0 \ Extensions, który miał zupełnie inną wersję. Nie wiemy, w jaki sposób pojawił się ten plik wykonywalny kompilatora, ani jak został przywoływany przez MSBuild, ale po usunięciu MSBuild powrócił do używania wersji csc.exe w swoim macierzystym katalogu Bin, a kod jest teraz poprawnie zbudowany.

+0

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

+0

@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. –