Раскрытие цели

Весьма любопытно, что так никто и не догадался, зачем в компиляторе мне понадобился код для преобразования списка аргументов метода в формат, при котором вначале выполняются выражения, содержащие побочные эффекты, эти результаты сохраняются в переменных, а затем уже выполняется метод с переменными, не содержащими побочных эффектов. Хотя в комментариях определенно были просто замечательные идеи по этому поводу!

А причина весьма прозаическая. У нас есть ошибка в коде, который выполняет семантический анализ вызовов с именованными аргументами. Одно из правил в языке C#, о котором я часто говорил в этом блоге, заключается в том, что вычисление подвыражения происходит в порядке слева на право. Если у вас есть метод void M(int x, int y) {}, который вызывается таким образом: M(y : F(), x : G()); мы не можем просто сгенерировать код, будто бы вы написали M(G(), F()). Побочные эффекты от выполнения метода F должны происходить до побочных эффектов от выполнения метода G, поэтому мы генерируем код, будто бы вы написали следующее: temp1 = F(); temp2 = G(); M( y : temp1, x : temp2); и теперь мы может сгенерировать вызов M(temp2, temp1); не переживая за изменение порядка побочных эффектов. Ошибка заключалась в том, что рерайтер (rewriter) выполнял неправильное переупорядочивание для ref/out-параметров или для аргументов в виде локальных переменных без побочных эффектов. Как всегда, при исправлении ошибки, я понял, что исходная ошибка связана с тем, что спецификация рерайтера была неполной.

Это исправление попадет в первый релиз C# 4, но проблемы, на которые указал Павел, такие странные побочные эффекты, как генерация исключений при доступе к неверному индексу массива или порядок выполнения статических конструкторов класса, моим алгоритмом не охватываются, и они не будут исправлены до первого релиза. Для корректного решения этой проблемы потребуется возможность генерации временных переменных с типом «ссылка на аргумент», которые мы никогда не применяли и для которых наш IL-генератор просто не предназначен. Если бы мы нашли эту ошибку раньше, возможно смогли бы ее нормально исправить, но сейчас уже слишком поздно.

Еще раз спасибо Павлу за отличный анализ и спасибо нашему старому другу nikov за своевременный отчет об ошибке.

Оригинальное сообщение: The Purpose, Revealed