Если мы правильно перевели сообщение о языке, то имеет место такой факт:
> -- Цитата:
> Хотя тип SIZE - со знаком, а ADDRESS - без знака, эти типы считаются совместимыми по присваиванию в обоих направлениях.

Учитывая, что тип SIZE интенсивно применяется, получается дыра в типобезопасности размером почти с адресную арифметику, а то и шире. У меня уже был один случай, когда из-за этого мой код не работал (перепутал параметр и вместо кода записи в реестре строк передавал адрес записи, или наоборот). С учётом того, что эта проблема была закопана и проявлялась только косвенно, это доставило немало неприятных минут (или часов, не помню уже).

По смыслу SIZE - это разность адресов и именно так она у меня и переведёна в настоящее время. Сам по себе адрес отрицательным быть не может. Поэтому присваивание от SIZE к адресу смысла не имеет: отрицательные адреса ничему не соответствуют, а положительные не покрывают всего диапазона адресов. Обратная ситуация не лучше: адреса, превышающие MAX(SIGNED32), превратятся в отрицательные значения SIZE. Полагаясь на поведение при переполнении, всё же этим типом иногда можно пользоваться. Хотя в языке я не заметил, чтобы поведение при переполнении было определено, значит, по-хорошему, им пользоваться нельзя.

Кроме использования для вычислений над адресами и размерами объектов в байтах, SIZE используется в качестве счётчика. Таким образом, мы можем написать что-то такое:

## Код:
```
PROCEDURE z(ptr: POINTER TO myRecord, arr: ARRAY OF INTEGER);
VAR counter : SIZE;
VAR adrOfNextRecord : SIZE;
BEGIN
  adrOfNextRecord := ADDRESS(ptr); (* или VAL(ADDRESS,ptr), не помню и не суть. 
       Но случайно результат оказался MAX(INTEGER)-1 *)
  FOR counter := 0 TO LEN(arr)-1 DO
    adrOfNextRecord := adr + counter (* ошибка размерности: сложили счётчик с адресом *)
    (* неопределённое поведение: переполнение целого числа *)
    END;
  RETURN VAL(POINTER TO myRecord, adrOfNextRecord)
END  z
```

Я не каждый месяц использую VAL и ADDRESS, поэтому мог ошибиться с преобразованиями,
но я думаю, смысл ясен: совместимость по присваиванию порождает ряд ошибок.

Как починить? Я бы сделал следующее:
делим тип SIZE на два. Один называется "счётчик" и полностью эквивалентен INTEGER и используется для счётчиков. Хотя я бы сделал рискованный шаг и сделал бы его эквивалентным SIGNED32 - ведь плохо, когда счётчик является платформо-зависимым - такой счётчик нужен лишь в отдельных случаях. Второй тип называется "разностьАдресов"Значению типа ADDRESS (адресВПамяти) можно присваивать только другой тип ADDRESS.Можно явно преобразовывать беззнаковые типы к типу ADDRESSК типу адресВПамяти можно прибавлять, а можно вычитать из него значение типа "разностьАдресов", и результатом является адресВПамятиРазность адресов можно складывать с разностьюАдресов и умножать на целое число - получится опять разностьАдресовSIZEOF () возвращает неотрицательную разностьАдресов (как следствие, никакой объект не может занимать более половины адресного пространства - это чуднО, но более-менее терпимо. Можно решить за счёт дальнейшего усложнения системы типов или установить правила переполнения).
Далее придётся написать инструмент для автотрансляции, который для каждого применения типа SIZE решит, в какой из двух типов его превратить. Пока не уверен, что это будет легко. Общая идея - смотреть, как применяется данная переменная и решать, превратить ли её в SIGNED32 (если это чисто счётчик) или в "разностьАдресов" (если она участвует в вычислениях с адресами). В последнем случае трудность состоит в анализе вызовов процедуры, что требует глобального анализа всей кодовой базы. Мой текущий инструментарий и с первой задачей едва справится, а со второй - вообще не справится.
SIZE встречается в соврменных исходниках ЯОС 13000 раз, а ADDRESS - 8000 раз. Т.е. делать вручную малореально.

Как более простой вариант - во всех местах, где происходит присвоение SIZE к ADDRESS и обратно, вставить явное преобразование - это должно быть нетрудно, а далее грепом найти эти преобразования и, возможно, руками или автоматически разметить, что в этом месте нужно превратить SIZE в разностьАдресов.  В остальных случаях превратить в SIGNED32. Но при этом не трогать сигнатуры процедур.