Вариантные записи ослабляют надежность типов?
В языке Pascal проверка типов вариантных записей считается невозможной.
Выдвигают две причины:? Программа может изменять тег без изменения какого-либо варианта, поэтому разработчики языка игнорируют возможность проверки.
? Программист может пропустить тег, делая запись свободным объединением. Имя тега вообще может быть пропущено, как в следующем объявлении типа t:
Тип записи t состоит только из вариантной части, то есть является объединением. По замыслу автора, имя типа вид после слова Case обеспечивает, что вариантная часть может быть в одном из двух состояний.
Но здесь нет имени тега, поэтому система полагает, что нет и тегового поля. Если есть объявление var x : t;
то возможные поля для переменной: x.i или x.r.
Состояние в записи не запоминается, поэтому нельзя проверить, в каком реальном состоянии находится объект х.
В языке Ada синтаксис и семантика вариантных записей языка Pascal были значительно улучшены, обеспечив существенное повышение безопасности. Здесь решены обе проблемы вариантных записей языка Pascal:
? запрещено изменение тега без изменения варианта;
? тег обязателен во всех вариантных записях.
Мало того, в языке Ada тег проверяется при любых обращениях к вариантным объектам. Перепишем рассмотренный выше вариантный тип узел в терминах языка Ada:
продолжение # |
274 |
Глава 10. Составные типы данных |
Здесь полная информация о теге записывается в заголовке типа (в круглых скобках) и называется дискриминантом типа. При объявлении переменной значение дискриминанта нужно обязательно указывать: вершина : узел (два); Переменная вершина называется ограниченной вариантной переменной. Ее вари- ант выбран и не может меняться при выполнении программы. Тег, использованный при объявлении ограниченной вариантной переменной, интерпретируется как именованная константа. Существует и другая возможность. Если в объявлении вариантного типа предус- мотрено значение по умолчанию, то на его основе можно объявлять неограниченные вариантные переменные. Например, на основе типа
можно объявить неограниченную вариантную переменную: вершина2 : узел; При ее объявлении тег не указывается, вариант переменной выбирается по умолчанию (в данном случае это лист), но появляется дополнительная возможность: изменение варианта переменной во время выполнения программы. Однако вариант переменной может поменяться только при присвоении ей (например, с помощью агрегата) значения целой записи, в том числе и тега. Например: вершина2 := (K ^ один, C1 ^ "not ", C2 ^ 2, потомок ^ "extn"); Подобное решение полностью исключает возможность несовместимости вариантных записей: ? если присваивается набор констант, то значение тега и вида варианта подвергается статической проверке на совместимость; ? если присваивается значение переменной, то совместимость гарантируется самим процессом присваивания, поскольку переменная из левой части становится копией переменной из правой части. Таким образом, эта реализация вариантных записей совершенно безопасна и обеспечивает проверку типов во всех случаях, хотя неограниченные вариантные переменные и должны проверяться динамически. |
Множества |
275 |