скалогрыз писал(а):держим кулачки, чтобы компилятор не начал тупить с advanced record-ами.
Конкретно с этим он не тупит, бинарной разницы между методом объекта и обычной процедурой с первым параметром «var self» нет. Я сейчас попробовал сделать две процедуры, статическую с var-параметром и метод без параметра —
- Код: Выделить всё
type
MyRec = record
msg: string;
class procedure PrintMsgStatic(var t: MyRec); static;
procedure PrintMsg;
end;
class procedure MyRec.PrintMsgStatic(var t: MyRec);
begin
t.PrintMsg;
end;
procedure MyRec.PrintMsg;
begin
writeln(msg);
end;
— и работа PrintMsgStatic сводится к немедленной передаче управления PrintMsg, даже без перекладывания регистров. То есть они буквально во всём, кроме внешности, скорее всего, полностью эквивалентны. Кроме того, с какой-то (~3.0) версии компилятора class static-процедуры совместимы с обычными (не «of object») процедурными указателями по присваиванию. (Но они и до этого были совместимы бинарно, поэтому можно было привести насильно.)
скалогрыз писал(а):а с обычными процедурами разве есть конфликты?
Ну тип в Си static-процедуры локальны для .c-файла. Вряд ли прям конфликты будут часто встречаться (т. е. даже локальные функции в разных файлах редко называют одинаково... хотя именно что «редко», а не «никогда»), но как тематическое разделение механизмом, альтернативным механизму модулей, удобно: процедуры внутри одного record'а могут вызывать друг друга без префиксов, внутри record'а можно, совсем как в модуле, объявить вложенные type/const/etc., опять же, доступные методам record'а без префикса, и всё такое.
скалогрыз писал(а):на сколько я понимаю, "классическая разбивка на inflate/deflate" связана с просто с разделением задач: упаковка отдельно, распаковка отдельно.
Тогда утилита, которая занимается только распаковкой данных, не будет обременена лишним кодом.
Не только, там отдельные модули для подзадач inflate/deflate (генерации деревьев и т. д.). Это удобно разработчику самой библиотеки, но вообще-то не очень удобно для её пользователя — в том числе по этой причине финальный результат иногда склеивают в один файл, как SQLite amalgamation.
Неиспользуемый код будет полностью выброшен, вот прям будто его и не было, так что весь оверхед в скорости компиляции частей, которые заведомо не понадобятся. Правда, не знаю, этим занимается компилятор сразу, увидев, что не было обращений к членам типа — идеальный вариант, или линковщик — тогда это не очень приятно, но какая разница. Для LCL-классов, например, этого не делается только потому, что они скомпилированы с RTTI ({$M+} / {$TYPEINFO ON}), которая предполагает, что методы могут, например, быть вызваны по имени, поэтому их, а за ними и всё, что они используют, выбросить низзя.