budden писал(а):
Сами по себе теги типа дают неустранимые накладные расходы. Т.е. конечно может быть где-то и есть докторская о том, как их убрать, но мне не попадалась...
Где-то было расширение для Оберонов, предлагающее "открытоподобные" массивы -- в качестве локальных переменных, где их длина задаётся в виде константных выражений на основе аргументов процедуры (реализация "резинового" стека на манер Ada).
По аналогии, в качестве бреда, исходя из предположения, что уже отработана техника условно произвольных (с ограниченими) константных выражений и выявления необходимых зависимостей, можно реализовать тип "динамической" записи в таком стиле:
Код:
TYPE Rec = RECORD
size: INTEGER;
a: ARRAY size OF INTEGER;
b: ARRAY size * 2 OF INTEGER;
END
Выше размеры массивов a и b зависят от size -- ака "дискриминант" записи на манер Ada. Операция NEW для такой записи (указателя) должна требовать обязательной установки значения для поля size, пусть в стиле Modula:
Код:
VAR r: POINTER TO Rec;
...
NEW(r, size := 10);
В отличие от случая, если бы поля a и b имели бы тип указателя на открытый массив, в данном случае предполагается единое выделение памяти для всей записи (вместо отдельных дополнительных операций для каждого массива), нет скрытого хранения размеров массивов (где-то в "тегах" для каждого массива), нет хранения указателей на массивы.
В случае отсутствия полей-"дискриминантов" в "динамической" записи размеры массивов необходимо указывать в операции NEW:
Код:
TYPE Rec = RECORD
a: ARRAY OF INTEGER;
b: ARRAY LEN(a) * 2 OF INTEGER;
END;
...
VAR r: POINTER TO Rec;
...
(* компилятор для NEW должен требовать установки размера для поля "a": *)
NEW(r, LEN(a) := 10);
Такие массивы/динамические записи не ликвидируют "теги" для типов, но снижают их "нагрузку", уменьшают потребность в обходных хаках (особенно в языке с ограниченными операциями над указателями).
Конструктив не изменяется, если в язык ввести и "неконтролируемые" массивы (без "тегов") для "ручного" управления памятью (что, скорее, возможно в той же Modula) -- аналог "array[0..0] of ..." в Pascal/Delphi (может быть в иной форме, чем результат Си-шного влияния, аля "UNTRACED ARRAY OF ...").