Ада-95. Компилятор GNAT
66ac8edd

Проверка порядка элаборации


В некоторых языках программирования, которые подразумевают наличие аналогичных проблем элаборации (например Java и C++), программист вынужден заботиться о порядке элаборации самостоятельно.

В следствие этого, часто встречаются случаи написания программ в которых выбор неправильного порядка элаборации приводит к неожиданным результатам, поскольку при этом используются переменные, значения которых не инициализированы.

Язык Ада был разработан как надежный язык и заботы программиста о порядке элаборации не так значительны.

В результате, язык предусматривает три уровня защиты:

Стандартные правила элаборации

накладывают некоторые ограничения на выбор порядка элаборации.

В частности, если какой-либо модуль указан в спецификаторе with, то элаборация его спецификации всегда осуществляется перед элаборацией модуля, который содержит этот спецификатор with.

Подобным образом, элаборация спецификации модуля-предка всегда осуществляется перед элаборацией спецификации модуля-потомка, и, в заключение, элаборация спецификации всегда осуществляется перед элаборацией соответствующего тела.

Динамические проверки элаборации

осуществляются во время выполнения программы.

Таким образом, если доступ к какой-либо сущности осуществляется до ее элаборации (обычно это происходит при вызовах подпрограмм), то возбуждается исключение Program_Error.



Средства управления элаборацией

позволяют программисту явно указывать необходимый порядок элаборации.

Рассмотрим перечисленные возможности более детально.

Во-первых, правила динамической проверки.

Одно из правил заключается в том, что при попытке использования переменной, элаборация которой не была выполнена, возбуждается исключение Program_Error.

Недостатком такого подхода является то, что затраты производительности на проверку каждой переменной могут оказаться достаточно дорогостоящими.

Вместо этого, Ada95 поддерживает два несколько более строгих правила, соблюдение которых легко проверить:

  • Ограничения для вызовов подпрограмм - Какая-либо подпрограмма может быть вызвана в процессе элаборации только в случае, когда осуществлена элаборация тела этой подпрограммы.




    Такое правило гарантирует, что элаборация спецификации подпрограммы будет выполнена перед вызовом подпрограммы, а не перед элаборацией тела.

    При нарушении этого правила возбуждается исключение Program_Error.

  • Ограничения для конкретизации настраиваемых модулей - Настраиваемый модуль может быть конкретизирован только после после осуществления элаборации тела настраиваемого модуля.

    Такое правило гарантирует, что элаборация спецификации настраиваемого модуля будет выполнена перед конкретизацией настраиваемого модуля, а не перед элаборацией тела.

    При нарушении этого правила возбуждается исключение Program_Error.

    Смысл идеи заключается в том, что при осуществлении элаборации тела элаборация любых переменных, которые используются в этом теле, должна быть уже выполнена.

    Таким образом, при проверке элаборации тела гарантируется, что ни один из ресурсов, которые использует это тело, не окажется источником каких-либо неожиданностей.

    Как было замечено ранее, такие правила несколько более строгие, поскольку необходима гарантия корректности вызова подпрограммы, которая использует в своем теле не локальные для этой подпрограммы ресурсы.

    Однако, полностью полагаться на эти правила будет не безопасно, поскольку это подразумевает, что вызывающая подпрограмма должна заботится о деталях реализации, которые размещенны в теле, что противоречит основным принципам Ады.

    Вероятная реализация такой идеи может выглядеть следующим образом.

    С каждой подпрограммой и с каждым настраиваемым модулем может быть ассоциирована логическая переменная.

    Первоначально такая переменная имеет значение "ложь" (False), а после осуществления элаборации тела эта переменная устанавливается в значение "истина" (True).

    Проверка значения этой переменной выполняется при осуществлении вызова или конкретизации, и когда значение переменной - "ложь" (False), возбуждается исключение Program_Error.


    Содержание раздела