Oleg N. Cher писал(а):
Больше похоже на то, что любой указатель, что тегированный, что безтеговый, не будет трассироваться сборщиком, покуда на нём не сделают NEW. Поэтому в биндингах часто применяются указатели без [untagged]. Меня это смущало, когда я думал, что безтеговость указателя не даёт выделять под него память по NEW. Ну а раз даёт, тогда в чём разница?
Смотри, отец родной - пока ты не сделаешь NEW, конечно, он NIL - сборщик по нему не пойдёт
Безтеговость указателя (POINTER [untagged] TO SomeRec) - это когда сам RECORD ББ-шный, тегированный. Т.е. этот указатель совершенно совместим по присваиванию с POINTER TO SomeRec, с полностью контролируемым указателем.
Просто для POINTER [untagged] поля внутри записи или глоб переменной она не регистрируется в таблице трассируемых указателей - и сборщик вообще не пойдёт по этому указателю, он не станет якорем. Если только такой указатель есть, то объект будет собран (а повисший указатель останется).
А POINTER TO RECORD [untagged] - это когда сама запись динамически выделена не диспетчером памяти ББ, тега типа не имеет, расширяться не может, WITH/IS не поддерживает и т.п.
В биндингах - ошибочно применять без RECORD [untagged] (именно RECORD, а не POINTER)! (только если это не действительно случай передачи во внешнюю либу указателя на ББшный объект, который обычный - и надо к его телу пустить внешнюю либу).
Если в биндинге именно к тебе в ББ, "на приём" приходит не-untagged-указатель, то это крах. Крах для сборщика: он пытается пойти по этому указателю, посмотреть по -4 адрес Kernel.Type-а для него - и всё.
Однако, если такой указатель побыл чисто на стеке - то да, этого никто не заметит. Ибо маркировка стека - консервативная, без разбора метаинформации.