Ответ 1
Я не совсем понимаю суть вопроса. Похоже, вы спрашиваете: "Почему компилятор создает неоптимизированный код, когда переключатель оптимизации отключен?" который сам отвечает.
Однако, я возьму на него удар. Я думаю, что вопрос на самом деле что-то вроде "какое конструктивное решение заставляет компилятор выпустить объявление, хранить и загружать локальные # 1, которые можно оптимизировать?"
Ответ заключается в том, что неоптимизированный кодеген разработан, чтобы быть ясным, однозначным, легко отлаживать и поощрять джиттер генерировать код, который не агрессивно собирает мусор. Одним из способов достижения всех этих целей является создание локалей для большинства значений, которые идут в стек, даже временных значений. Давайте рассмотрим более сложный пример. Предположим, что у вас есть:
Foo(Bar(123), 456)
Мы могли бы сгенерировать это как:
push 123
call Bar - this pops the 123 and pushes the result of Bar
push 456
call Foo
Это хорошо, эффективно и мало, но это не соответствует нашим целям. Он ясен и недвусмыслен, но отлаживать его непросто, потому что сборщик мусора может стать агрессивным. Если Foo по какой-то причине фактически ничего не делает с его первым аргументом, GC может вернуть возвращаемое значение Bar до запуска Foo.
В неоптимизированной сборке мы будем генерировать нечто большее, чем
push 123
call Bar - this pops the 123 and pushes the result of Bar
store the top of the stack in a temporary location - this pops the stack, and we need it back, so
push the value in the temporary location back onto the stack
push 456
call Foo
Теперь у дрожания есть большой намек, в котором говорится: "Эй, дрожь, держи это живое в локальном какое-то время, даже если Foo его не использует"
Общее правило здесь - "сделать локальные переменные из всех временных значений в неоптимизированной сборке". И так вы идете; для оценки выражения "if" нам нужно оценить условие и преобразовать его в bool. (Конечно, условие не должно быть типа bool, оно может быть типа, неявно конвертируемого в bool, или типа, реализующего ложную пару оператора true/operator.) Неоптимизированному генератору кода было сказано "агрессивно поворачивать все временные значения на локальных жителей", и так, что вы получите.
Я предполагаю, что в этом случае мы могли бы подавить это на временных условиях, которые являются условиями в операциях if, но это звучит как работа для меня, которая не имеет пользы для клиента. Поскольку у меня есть стек работы, пока у вашей руки есть ощутимая польза для клиента, я не собираюсь менять неоптимизированный генератор кода, который генерирует неоптимизированный код точно так, как предполагается.