VBETER-Iterator-Funktion verliert lokale Variablen

9

Nach einem Paar showstoppers verzögerte Migration auf die .NET 4.6 Runtime Ich war endlich mit der Umstellung auf die C # 6 / VB14-Compiler zufrieden, bis ich auf ein kritisches Problem stieß, bei dem Iterator-Funktionen in VB.NET lokale Variablen wegwarfen.

Im folgenden Codebeispiel wird eine NULL-Verweisausnahme in der kommentierten Zeile ausgelöst, wenn sie im Veröffentlichungsmodus (optimiert) in Visual Studio 2015 / msbuild kompiliert wurde.

%Vor%

Also, das ist ziemlich beängstigend.

Insbesondere wird das C # -Äquivalent dieses Codes ohne Problem ausgeführt. Noch wichtiger ist, dass dies unter früheren Versionen des VB-Compilers funktioniert (und auch funktioniert hat). Beim Vergleich der MSIL zwischen der von den beiden verschiedenen Compilern erstellten Zustandsmaschine scheint der neue Compiler fast ausschließlich .locals für den lokalen Variablenspeicher zu verwenden, während der alte Compiler veränderbare Felder auf der Zustandsmaschine zum Speichern lokaler Werte verwendete.

>

Vermisse ich etwas? Ich konnte keine Dokumentation einer brechenden Änderung mit Iteratoren in VB finden (ich kann mir auch nicht vorstellen, dass dies der Fall wäre), aber ich habe auch niemanden gefunden, der dieses Problem gelöst hat.

Dieses spezielle Beispiel kann umgangen werden, indem man die Konstruktion von map nach der ersten foreach-Schleife verschiebt, aber meine Sorge ist, dass ich keinen Sinn für den wahren Geschmack dieses Problems habe. Ich bin nicht daran interessiert, den Code so zu ändern, dass er einfach funktioniert. Wo sonst in unserer umfangreichen Codebasis könnte ich auf ein Problem stoßen? Ich habe das Problem auf Connect aber übermittelt das fühlt sich oft wie ein schwarzes Loch an.

AKTUALISIEREN

Jemand hat gerade das gleiche Problem mit der Async-Statusmaschine auf der Roslyn GitHub-Seite gemeldet: Ссылка

Hoffentlich fängt das an, ein wenig Aufmerksamkeit zu bekommen.

    
roken 23.02.2016, 03:41
quelle

1 Antwort

1

Zunächst einmal vielen Dank, dass Sie dem Thema, das ich mit dem Roslyn-Team angesprochen habe, etwas Aufmerksamkeit geschenkt haben.

Ich habe die neueste Roslyn-Quelle aus Ссылка (Masterzweig) gezogen und dem BasicCompilerEmitTest-Projekt einen zusätzlichen Komponententest hinzugefügt sieht so aus:

%Vor%

Dies kann aufgrund der Verwendung von XElement und XCData wie ein verschachteltes Durcheinander aussehen, aber dies ist das Format, das von anderen Roslyn-Komponententests verwendet wird.

Ich habe nur eine Änderung an dem Code vorgenommen, den Sie in Ihrer Frage gepostet haben - das heißt, Console.ReadKey() durch Console.WriteLine("done") zu ersetzen, damit ich den erfolgreichen Abschluss verfolgen konnte (da CompileAndVerify einfach Ausnahmen ignoriert).

Der obige Test besteht. Es gibt kein NullReferenceException auf map.Values access, und die Ausgabe ist:

%Vor%

... wie erwartet. Es scheint daher, dass Ihr Fehler behoben wurde - obwohl, ob das Update mit Visual Studio 2015 Update 2 ausgeliefert wird, kann ich nicht sagen.

Das async-Problem mit der variablen Erfassung wurde von pull Anfrage # 7693 , aber DataFlowPass.SetSlotUnassigned wurde seit (in zwei Methoden aufgeteilt und modifiziert) neu geschrieben, so dass ich nicht bestätigen kann, ob das von Ihnen entdeckte Iteratorproblem durch diesen spezifischen Pull behoben wurde Anfrage oder durch eine andere Codeänderung.

    
Kirill Shlenskiy 24.02.2016, 02:15
quelle