2014-09-08 5 views
6

Wir haben die folgende Methode in einer Klasse in einem unserer Projekte:Compilation lässt Code nach festen Blöcken in bestimmten Methoden

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 
} 

Ich habe dies zu verschleiern hatte, aber es ist hoffentlich noch klar genug, um eine bekommen Vorstellung von dem, was vor sich geht.

Auf einer unserer Entwicklermaschinen entfernt der C# -Compiler in debug-Builds die drei Zuordnungen, die auftreten, nachdem der fixed-Block geschlossen wurde. Wenn wir versuchen, einen Haltepunkt in diese Zeilen einzufügen, springt der Haltepunkt beim Start der Anwendung zur Endstrebe der Methode. Code, der zwischen einem fixed Block und dem Ende einer Methode erscheint, wird auch in anderen Methoden entfernt, aber rätselhaft, nicht in allen.

Nach einigen Experimenten haben wir festgestellt, dass auf Optimierung für das betroffene Projekt den fehlenden Code enthalten verursacht. Diese Umgehung schlägt jedoch bei unseren Unit-Tests fehl - der Code fehlt, und die Änderung der Optimierung des betroffenen Projekts und seines Testprojekts hilft nicht. Wir haben auch festgestellt, dass das Verschieben der drei Zuordnungen innerhalb der innersten fixed-Anweisung funktioniert hat - es wird klar, warum bei der Untersuchung der IL.

In dem Debug-DLL auf der betroffenen Maschine gebaut (mit Optimierung ausgeschaltet), erscheint eine Rückkehr op direkt nach ap von dem Stapel genommene ist:

IL_03a1: nop 
IL_03a2: ldc.i4.0 
IL_03a3: conv.u 
IL_03a4: stloc.s ap 
IL_03a6: ret 

Dies erklärt, warum vor den stloc die drei Zuweisungen bewegen Anweisung funktioniert. In dem Debug-DLL auf meinem Rechner gebaut, erfolgt die Rückkehr op in der erwarteten Stelle, nach den drei Aufgaben:

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 

Wir haben eine SSCCE es bisher versäumt, zu produzieren - dies scheint nur unter ganz bestimmten Umständen zu manifestieren und nur in einem unserer Projekte. Wir haben überprüft, dass die gleichen Versionen von Visual Studio, das .NET-Framework, der C# -Compiler und MSBuild auf beiden Computern verwendet werden. Wir haben andere mögliche Unterschiede wie OS-Version und Updates überprüft. Die Dinge scheinen auf beiden Maschinen gleich zu sein (sie sind das gleiche Modell des Laptops). Wir sind ein wenig verwirrt, ehrlich gesagt. Jede Hilfe würde sehr geschätzt werden.

Antwort

0

Mein Kollege, der Entwickler, dessen Maschine dies beeinflusste, fand einen Unterschied in der Diagnoseausgabe vom Build - es war der C# -Compiler. Wir dachten, dass MSBuild die csc.exe am erwarteten Speicherort (c: \ Programme (x86) \ MSBuild \ 12.0 \ Bin) verwendet, aber bizarrerweise führte es tatsächlich eine csc.exe in C: \ Users aus \ [Benutzer] \ AppData \ Local \ Microsoft \ VisualStudio \ 12.0 \ Erweiterungen, die eine völlig andere Version hatte. Wir wissen nicht, wie das Compiler-Programm dorthin kam oder wie es von MSBuild referenziert wurde, aber sobald es entfernt wurde, verwendete MSBuild die Version von csc.exe in seinem Home-Bin-Verzeichnis und der Code wurde wiederhergestellt jetzt korrekt gebaut.

+0

Ist das nicht der Roslyn-Compiler? Ich habe das in C: \ Benutzer \ Svick \ AppData \ Lokale \ Microsoft \ VisualStudio \ 12.0 \ Extensions \ 2wcdsyh.hslm \ rcsc.exe. Wenn dies der Fall ist, sollten Sie [diesen Fehler dem Roslyn-Team melden] (https://roslyn.codeplex.com/WorkItem/Create). – svick

+0

@svick Das ist ein interessanter Anhaltspunkt - ich werde am Montag von meinem Kollegen erfahren, ob er den Roslyn-Compiler installiert hat und wenn er das Problem dem Roslyn-Team meldet. Ich melde mich zurück. –