iskander писал(а):А constref это просто гарантия передачи по ссылке
Так передача неизменяемого параметра по ссылке и по значению неотличимы в чистом Pascal-коде, это нужно только для бинарной совместимости с C API или ассемблером. Мотивация введения constref заключалась в том, что если у тебя есть C-функция
- Код: Выделить всё
__declspec(dllexport) void SetBodyVelocity(Body* body, const Vec3* velocity);
— то раньше, чтобы соблюсти бинарную совместимость, приходилось импортировать её с var (ну или с явным PVec3, будет всё то же самое):
- Код: Выделить всё
procedure SetBodyVelocity(body: PBody; var velocity: Vec3); external ...
И такую функцию нельзя напрямую вызвать с Vec3, сконструированным на месте: SetBodyVelocity(body, MakeVec3(1, 0, 0)) не скомпилируется из-за ограничения var на lvalue — объявленные переменные. constref указывает компилятору, что допустимо передать под капотом указатель на rvalue — невидимую временную переменную с результатом MakeVec3.
В случае операторов constref нужен
только в class operator Copy (иначе компилятор его не узнает), и то это багофича, обусловленная внутренней реализацией managed operators (они записываются в RTTI, откуда могут быть вызваны над заранее неизвестным типом функциями вроде CopyArray). Его использование без повода может сгенерировать менее оптимальный код, т. к. той самой «временной переменной» на стеке могло вообще не быть.