Ассемблерный код для оператора и процедуры совпадает один в один, оператор возвращает результат в неявном out-параметре.
Однако результат оператора в явном виде присваивается одному из его аргументов. Компилятор имеет довольно-таки навернутые проверки на предмет того, можно ли удалить временную переменную с результатом ф-ции, но конкретно в таком случае эта временная переменная остается. Внутри оператора должно быть возможным читать аргументы после записи в результат, компилятор обеспечивает правильность кода, жертвуя скоростью.
В варианте с out ответственность переходит с компилятора на тебя: если внутри ф-ции читать v1 после записи в result, получишь неверный результат, и компилятор с этим ничего не поделает.
Замени v1:=v1+v2 на v:=v1+v2 (v - еще одна переменная типа TVec4f), и оба теста выдадут одинаковые результаты.
Иделогически правильная сигнатура для этого случая выглядит так:
procedure add(var Dest: TVec4f; const Src: TVec4f);
S!V писал(а):И ещё, я прочитал, что FPC team собирается использовать Static single assignment для оптимизатора в следующей версии компилера. Сам толком не знаю, что это. Может ли это исправить описанную ситуацию?
Может быть. *Что-то* от этого точно улучшится. Но, боюсь, ситуацию с присваиванием результата ф-ции одному из аргументов можно разрулить только путем глобальной оптимизации кода, о которой пока что никто даже не заикался.
S!V писал(а):ЗЫ. Есть идея добавления out-директивы для функций. Т.е. что-то вроде Код:
function A :Integer; out;
Чтобы Result внутри функции трактовался как параметр процедуры, как будто описанный в заголовке как "out Result :Integer". Это избавит от необходимости копирования результата после выхода из функции. Имеет смысл оставлять запрос на фичу в багрепортере? Т.е. имеет ли она шансы быть внедрённой, или разработчики забивают на подобные запросы, кто-нибудь знает?
Это смысла не имеет, потому что уже сделано. Все результаты "не-элементарных" типов (записи, строки, массивы, variant) возвращаются в неявных out-параметрах. Элементарные типы (integer и т.п.) возвращаются в регистрах процессора, потому что это быстрее всего. Копирование результата удаляется в тех случаях, когда компилятор может это сделать, не нарушив правильносии кода.