Bayrak yaymayı gizleyin localsinit .Suppress emitting of localsinit flag.

  • [x] önerilir[x] Proposed
  • [] Prototipi: başlatılmadı[ ] Prototype: Not Started
  • [] Uygulama: başlatılmadı[ ] Implementation: Not Started
  • [] Belirtimi: başlatılmadı[ ] Specification: Not Started

ÖzetSummary

Öznitelik aracılığıyla bayrağın bir şekilde bastırçıkmasına izin ver localsinit SkipLocalsInitAttribute .Allow suppressing emit of localsinit flag via SkipLocalsInitAttribute attribute.

MotivasyonMotivation

Arka PlanBackground

CLR spec başına, başvuruları içermeyen yerel değişkenler VM/JıT tarafından belirli bir değere başlatılmaz.Per CLR spec local variables that do not contain references are not initialized to a particular value by the VM/JIT. Başlatma olmadan bu tür değişkenlerden okuma tür açısından güvenlidir, aksi halde davranış tanımsız ve uygulamaya özgüdür.Reading from such variables without initialization is type-safe, but otherwise the behavior is undefined and implementation specific. Genellikle başlatılmamış Yereller, artık yığın çerçevesinin kapladığı bellekte kalan değerleri içerir.Typically uninitialized locals contain whatever values were left in the memory that is now occupied by the stack frame. Bu, belirleyici olmayan davranışa ve hataları yeniden oluşturmaya neden olabilir.That could lead to nondeterministic behavior and hard to reproduce bugs.

Yerel bir değişken "atama" için iki yol vardır:There are two ways to "assign" a local variable:

  • bir değeri depolayarak veyaby storing a value or
  • localsinityerel bellek havuzunu oluşturan her şeyin sıfır olarak başlatılmış olmasını zorlayan bayrak belirterek, bu hem yerel değişkenleri hem de stackalloc verileri içerir.by specifying localsinit flag which forces everything that is allocated form the local memory pool to be zero-initialized NOTE: this includes both local variables and stackalloc data.

Başlatılmamış verilerin kullanılması önerilmez ve doğrulanabilir kodda buna izin verilmez.Use of uninitialized data is discouraged and is not allowed in verifiable code. Akış Analizi ile ilgili olduğunu kanıtlamak mümkün olsa da, doğrulama algoritmasının koruyucu olması ve yalnızca ayarlanmış olması gerekir localsinit .While it might be possible to prove that by the means of flow analysis, it is permitted for the verification algorithm to be conservative and simply require that localsinit is set.

Tarihsel C# derleyicisi localsinit , yerelleri bildiren tüm yöntemlerde bayrak yayar.Historically C# compiler emits localsinit flag on all methods that declare locals.

C#, clr belirtiminin gerektirme süresinden daha sıkı olan kesin atama analizini kullanır (c# ' nin yerellerin kapsamını da değerlendirmesi gerekir), sonuçta ortaya çıkan kodun tek bir biçimde doğrulanabilir olması kesin değildir:While C# employs definite-assignment analysis which is more strict than what CLR spec would require (C# also needs to consider scoping of locals), it is not strictly guaranteed that the resulting code would be formally verifiable:

  • CLR ve C# kuralları yerel bir as bağımsız değişkeninin bir olarak geçirilip geçirilmediğini kabul etmeyebilir out use .CLR and C# rules may not agree on whether passing a local as out argument is a use.
  • Koşullar bilindiğinde CLR ve C# kuralları koşullu dallar sırasında kabul etmeyebilir (Sabit yayma).CLR and C# rules may not agree on treatment of conditional branches when conditions are known (constant propagation).
  • Buna localinits izin verildiğinden clr de yeterlidir.CLR could as well simply require localinits, since that is permitted.

SorunProblem

Yüksek performanslı uygulamada zorlanan sıfır başlatma maliyeti fark edilebilir.In high-performance application the cost of forced zero-initialization could be noticeable. Kullanıldığında özellikle dikkat çekici hale gelir stackalloc .It is particularly noticeable when stackalloc is used.

Bazı durumlarda JıT, sonraki atamalar tarafından bu başlatma "sonlandırıldı" olduğunda tek tek Yereller için ilk sıfır başlatma işlemi yapabilir.In some cases JIT can elide initial zero-initialization of individual locals when such initialization is "killed" by subsequent assignments. Tüm JITs bunu yapmayın ve bu iyileştirmenin sınırları vardır.Not all JITs do this and such optimization has limits. Konusunda yardımcı değildir stackalloc .It does not help with stackalloc.

Sorunun gerçek olduğunu göstermek için, herhangi bir yerelde bulunmayan bir yöntemin IL bayrak içermediği bilinen bir hata vardır localsinit .To illustrate that the problem is real - there is a known bug where a method not containing any IL locals would not have localsinit flag. Hata, stackalloc başlatma maliyetlerinin önüne geçmek için özellikle bu tür yöntemlere yerleştirilerek, kullanıcılar tarafından zaten kullanılıyor.The bug is already being exploited by users by putting stackalloc into such methods - intentionally to avoid initialization costs. Bunun nedeni, yerelin yokluğunun IL kararsız bir ölçüm olmasına ve CodeGen stratejisindeki değişikliklere göre değişebileceğini unutmayın.That is despite the fact that absence of IL locals is an unstable metric and may vary depending on changes in codegen strategy. Hatanın düzeltilmesi ve kullanıcıların, bayrağı gizlemeyi daha fazla belgelenmiş ve güvenilir bir şekilde alması gerekir.The bug should be fixed and users should get a more documented and reliable way of suppressing the flag.

Ayrıntılı tasarımDetailed design

System.Runtime.CompilerServices.SkipLocalsInitAttributeDerleyiciye bayrak yaymadığından söylemek için bir yol olarak belirtilmesine izin verin localsinit .Allow specifying System.Runtime.CompilerServices.SkipLocalsInitAttribute as a way to tell the compiler to not emit localsinit flag.

Bunun nihai sonucu, Yereller, C# ' de büyük olasılıkla bir test eden JıT tarafından sıfır olarak başlatılmamış olabilir.The end result of this will be that the locals may not be zero-initialized by the JIT, which is in most cases unobservable in C#.
Bu verilerin yanı sıra stackalloc , sıfır olarak başlatılamaz.In addition to that stackalloc data will not be zero-initialized. Bu kesinlikle Observable ' dır, ancak aynı zamanda en çok mücadele senaryosu da vardır.That is definitely observable, but also is the most motivating scenario.

İzin verilen ve tanınan öznitelik hedefleri şunlardır: Method , Property ,,,, Module Class Struct Interface , Constructor .Permitted and recognized attribute targets are: Method, Property, Module, Class, Struct, Interface, Constructor. Ancak derleyici, öznitelik listelenen hedeflerle tanımlanmalıdır veya özniteliğin hangi derlemede tanımlandığından emin olur.However compiler will not require that attribute is defined with the listed targets nor it will care in which assembly the attribute is defined.

Öznitelik bir kapsayıcıda belirtildiğinde (, class module , iç içe geçmiş bir yöntem,...), bayrak kapsayıcı içinde yer alan tüm yöntemleri etkiler.When attribute is specified on a container (class, module, containing method for a nested method, ...), the flag affects all methods contained within the container.

Birleştirme yöntemleri, mantıksal kapsayıcıdan/sahibe ait bayrağı "devralma".Synthesized methods "inherit" the flag from the logical container/owner.

Bayrak, gerçek yöntem gövdeleri için yalnızca CodeGen stratejisini etkiler.The flag affects only codegen strategy for actual method bodies. Yani.I.E. bayrak soyut yöntemleri etkilemez ve geçersiz kılma/uygulama yöntemlerine yayılmaz.the flag has no effect on abstract methods and is not propagated to overriding/implementing methods.

Bu, dil özelliği değil, açıkça bir derleyici özelliğidir .This is explicitly a compiler feature and not a language feature.
Benzer şekilde derleyici komut satırı anahtarlarına, özelliği belirli bir codegen stratejisinin uygulama ayrıntılarını denetler ve C# belirtimi için gerekli olması gerekmez.Similarly to compiler command line switches the feature controls implementation details of a particular codegen strategy and does not need to be required by the C# spec.

BulunmaktadırDrawbacks

  • Eski/diğer derleyiciler özniteliği karşılamayabilir.Old/other compilers may not honor the attribute. Özniteliğin uyumlu davranış yok sayılıyor.Ignoring the attribute is compatible behavior. Yalnızca hafif bir performans isabetini elde edebilir.Only may result in a slight perf hit.

  • Bayrak olmadan kod localinits doğrulama başarısızlıklarını tetikleyebilir.The code without localinits flag may trigger verification failures. Bu özelliği istemek için gereken kullanıcılar genellikle doğruıyabilme ile ilgilidir.Users that ask for this feature are generally unconcerned with verifiability.

  • Özniteliği bir bağımsız yöntemden daha yüksek düzeylerde uygulamak, kullanıldığında observable olan yerel olmayan etkiye sahiptir stackalloc .Applying the attribute at higher levels than an individual method has nonlocal effect, which is observable when stackalloc is used. Henüz bu, en çok istenen senaryodur.Yet, this is the most requested scenario.

AlternatiflerAlternatives

  • localinitsYöntem bağlamda bildirildiği zaman bayrak atlayın unsafe .omit localinits flag when method is declared in unsafe context. Bu durum, sessiz ve tehlikeli davranışların bir durumda belirleyici olmayan bir şekilde değişmesine neden olabilir stackalloc .That could cause silent and dangerous behavior change from deterministic to nondeterministic in a case of stackalloc.

  • localinitsher zaman bayrak atlayın.omit localinits flag always. Yukarıdakilerden daha da kötüsü.Even worse than above.

  • localinits stackalloc Yöntem gövdesinde kullanılmamışsa bayrak atlayın.omit localinits flag unless stackalloc is used in the method body. En çok istenen senaryoyu ele almaz ve bu geri dönüş seçeneği olmadan kodu doğrulanamaz olarak döndürebilir.Does not address the most requested scenario and may turn code unverifiable with no option to revert that back.

Çözümlenmemiş sorularUnresolved questions

  • Öznitelik gerçekten meta verilere yayınlansın mı?Should the attribute be actually emitted to metadata?

Tasarım toplantılarıDesign meetings

Henüz yok.None yet.