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



         

Код элаборации - часть 2


Например:

with Unit_1; package Unit_2 is ...

В данном случае необходимо, чтобы элаборация спецификации и тела модуля Unit_1

осуществлялась перед спецификацией модуля Unit_2.

Однако, такое правило накладывает достаточно жесткие ограничения.

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

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

Рассмотрим следующий пример.

Тело модуля Unit_1

содержит подпрограмму Func_1, которая использует переменную Sqrt_1

описанную в коде элаборации тела Unit_1:

Sqrt_1 : Float := Sqrt (0.1);

Код элаборации тела модуля Unit_1 также содержит:

if expression_1 = 1 then

Q := Unit_2.Func_2; end if;

Существует также модуль Unit_2, структура которого аналогична: он содержит подпрограмму Func_2, которая использует переменную Sqrt_2

описанную в коде элаборации тела Unit_2:

Sqrt_2 : Float := Sqrt (0.1);

Код элаборации тела модуля Unit_2 также содержит:

if expression_2 = 2 then

Q := Unit_1.Func_1; end if;

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

Spec of Unit_1 Spec of Unit_2 Body of Unit_1 Body of Unit_2

или последовательность вида:

Spec of Unit_2 Spec of Unit_1 Body of Unit_2 Body of Unit_1

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

Если выражение expression_1 не равно 1, а выражение expression_2 не равно 2, то можно использовать любую из показанных выше последовательностей элаборации, поскольку отсутствуют вызовы функций.

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

Если результат проверки одного условия истина (true), а другого - ложь (false), то одна из показанных последовательностей элаборации будет справедлива, а другая - нет.

Например, если expression_1 = 1 и expression_2 /= 2, то присутствует вызов Func_2, но нет вызова Func_1.

Это подразумевает, справедливость выполнения элаборации тела модуля Unit_1

перед элаборацией тела Unit_2, то есть первая последовательность элаборации правильна, а вторая - нет.

Если выражения expression_1 и expression_2

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

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




Содержание  Назад  Вперед