Здравствуйте, Sinclair, Вы писали:
Вот вам идея на двоих: нормальный код должен работать в "SkipLocalsInit", когда вот эти переменные на стэке физически не инициализируются, прям как в старые добрые времена.
Поэтому, мне неясно что там курит стандарт на самом деле.
На практике, это выглядит как:
_ = TryGetValue(out var x);
return x == 0; // привет, не проверили результат
Это особенно важно работая с нативным кодом, который не имеет привычки писать в выход, если нечего выводить. А соответственно, мы и не должны это читать.
В общем, теперь такое доступно в C# официально. И более того — любой уважающий себя человек (разрабатывающий библиотеку) — просто обязан это использовать (если крохи перфоманса — фактор). Это вроде крохи, но на stackalloc они совсем не крохи. Впрочем и выделять буфера стоит неинициализированными. ОС и так старается чистить нулями страницу, отдавая ее в пользование, а дальше простите, думайте сами (и дотнет по прежнему сугубо нелогичен в этом — BufferWriter идет на помойку первым же, именно поэтому, хотя это единственный его недостаток).
PS: Именно в рамках C# SkipLocalsInit — ничего не меняет (по крайней мере так заявляется). Активируется просто атрибутом:
[module: System.Runtime.CompilerServices.SkipLocalsInit]
. Тем не менее, это критично понимать, что компилятор перестанет генерировать очистки — в конце концов, out параметры часто выглядят неуклюже именно поэтому, и приходится использовать ref => а это именно путь наступить на предусмотрительно расставленные грабли.
Я сам воочию наблюдал именно насколько разительно меняется поведение в pinvoke, когда неправльный код проявляет себя, но, если остаться в рамках именно C# — не уверен, насколько это важно. С практической точки зрения — думаю 99.9% осмысленного кода может это взять, поиметь бенефиты, и будет работать без каких-либо последствий.