...
2. Сборщик мусоре НЕ МЕНЯЕТ эти адреса (во время сборки мусора и выделения памяти под обьекты)..
Вообще говоря, сборщик мусора может перемещать объекты (то есть менять адреса) и не собирая мусор (то есть не имея целью освобождение памяти). Компактификация/дефрагментация памяти.
Достаточно, чтобы сборщик мусора не менял адреса динамических объектов или вообще не вызывался лишь во время работы процедуры поиска. Возможно, что GC вообще не вызывается во время вызова процедур и загрузки-выгрузки модулей, как в КП.
Такую низкоуровневую процедуру можно реализовать в отдельном модуле через импорт SYSTEM, а внешний пользователь пусть видит только результат поиска.
Я так понимаю, если поиск идет в массиве ссылок типа "T", то процедура поиска будет эквивалентна чему-то такому:
PROCEDURE SearchPointerT* (IN a: ARRAY OF POINTER TO T; p: POINTER TO T; k: INTEGER; b: BOOLEAN): INTEGER;
BEGIN
ASSERT(k >= 0);
WHILE (k < LEN(a)) & ((a[k] = p) # b) DO
INC(k)
END
;RETURN
k (* (k = LEN(a)) OR ((a[k] = p) = b) *)
END SearchPointerT;
При "b = FALSE" - поиск первой ссылки несовпадающей с "p", начиная с "k"-ой;
при "b = TRUE" - поиск первой совпадающей с "p" ссылки, начиная с "k"-ой.
Для ссылок на списки в КП возможна общая процедура:
PROCEDURE SearchPointerRecord (IN a: ARRAY OF ANYPTR; p: ANYPTR; k: INTEGER; b: BOOLEAN): INTEGER;