Справочник по Ada (Ada 2022)
10.1.3 Подразделения единиц компиляции
Подразделения похожи на дочерние единицы, но с этими (важными) отличиями: подразделения поддерживают отдельную компиляцию только тел (а не объявлений); родительская единица содержит заглушку_тела для указания существования и местоположения каждого из её подразделений; объявления, присутствующие в теле родительской единицы, могут быть видимыми внутри подразделений.
Синтаксис
заглушка_тела ::=
заглушка_тела_подпрограммы | заглушка_тела_пакета
| заглушка_тела_задачи | заглушка_тела_защищенного_типа
заглушка_тела_подпрограммы | заглушка_тела_пакета
| заглушка_тела_задачи | заглушка_тела_защищенного_типа
заглушка_тела_подпрограммы ::=
[индикатор_переопределения]
спецификация_подпрограммы is separate
[спецификация_аспекта];
[индикатор_переопределения]
спецификация_подпрограммы is separate
[спецификация_аспекта];
заглушка_тела_защищенного_типа ::=
protected body идентификатор_определения is separate
[спецификация_аспекта];
protected body идентификатор_определения is separate
[спецификация_аспекта];
Правила допустимости
Тело родителя подразделения — это тело программной единицы, обозначенной его именем_родительской_единицы. Термин подразделение используется для обозначения подразделения и также для собственного_тела подразделения. Подразделения программной единицы включают любое подразделение, которое указывает на эту программную единицу как на родительскую, а также любое подразделение, которое указывает на такое подразделение как на родительскую (рекурсивно).
Тело родителя подразделения должно присутствовать в текущей среде и должно содержать соответствующую заглушку_тела с тем же идентификатором_определения, что и у подразделения.
Заглушка тела пакета должна быть завершением объявления пакета или объявления обобщенного пакета; заглушка тела задачи должна быть завершением объявления задачи; заглушка тела защищенного типа должна быть завершением объявления защищенного типа.
В отличие от этого, заглушка тела подпрограммы может быть определена без того, чтобы быть завершением предыдущего объявления, в этом случае заглушка объявляет подпрограмму. Если заглушка является завершением, она должна быть завершением объявления подпрограммы или объявления обобщенной подпрограммы. Профиль заглушки тела подпрограммы, которая завершает объявление, должен полностью соответствовать профилю объявления.
Подразделение, соответствующее заглушке_тела, должно быть того же типа (package_, subprogram_, task_ или protected_), что и заглушка_тела. Профиль подразделения тела_подпрограммы должен полностью соответствовать профилю соответствующей заглушки_тела.
Заглушка тела должна появляться непосредственно внутри декларативной_части тела единицы компиляции. Это правило не применяется внутри экземпляра обобщенной единицы.
Идентификаторы определения всех заглушек_тела, которые появляются непосредственно внутри конкретной декларативной_части, должны быть различными.
Правила после компиляции
Для каждой заглушки_тела должно быть подразделение, содержащее соответствующее собственное_тело.
ПРИМЕЧАНИЕ Правила в 10.1.4, «Процесс компиляции» говорят, что заглушка_тела эквивалентна соответствующему собственному_телу. Это подразумевает:
Видимость внутри подразделения — это видимость, которая была бы получена в месте соответствующей заглушки_тела (в теле родителя), если бы пункт_контекста подразделения был добавлен к пункту_контекста родительского тела.
Эффект выполнения заглушки_тела — это выполнение подразделения.
Примеры
Пример, который определяет пакет Parent без подразделений:
package Parent is
procedure Inner;
end Parent;
procedure Inner;
end Parent;
with Ada.Text_IO;
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
end Parent;
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
end Parent;
Пример, демонстрирующий, как тело процедуры Inner может быть преобразовано в подразделение, переписав тело пакета следующим образом (с оставшимся неизменным объявлением Parent):
package body Parent is
Variable : String := "Привет, там.";
procedure Inner is separate;
end Parent;
Variable : String := "Привет, там.";
procedure Inner is separate;
end Parent;
with Ada.Text_IO;
separate(Parent)
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;
separate(Parent)
procedure Inner is
begin
Ada.Text_IO.Put_Line(Variable);
end Inner;