Справочник по Ada 2005
6.4 Вызовы подпрограмм
Вызов подпрограммы — это либо оператор procedure_call_statement, либо function_call; он инициирует выполнение subprogram_body. Вызов задаёт сопоставление фактических параметров, если таковые имеются, с формальными параметрами подпрограммы.
Синтаксис
Сопоставление параметров parameter_association является именованным или позиционным в зависимости от того, указан ли formal_parameter_selector_name. Любые позиционные сопоставления должны предшествовать именованным. Именованные сопоставления не допускаются, если префикс prefix в вызове подпрограммы является ссылкой на атрибут attribute_reference.
Правила разрешения имён
Имя name или префикс prefix, заданный в операторе вызова процедуры procedure_call_statement, должен указывать на вызываемый объект, являющийся процедурой или переименованным входом (рассматриваемым как процедура). Имя name или префикс prefix, заданный в вызове функции function_call, должен указывать на вызываемый объект, являющийся функцией. Имя или префикс не должен указывать на абстрактную подпрограмму, если она не является также диспетчеризируемой подпрограммой. При наличии части параметров actual_parameter_part префикс может быть неявным разыменованием значения типа указатель на подпрограмму.
Вызов подпрограммы должен содержать не более одного сопоставления для каждого формального параметра. Каждый формальный параметр без сопоставления должен иметь выражение по умолчанию default_expression (в профиле представления, обозначаемого именем name или префиксом prefix). Это правило является правилом перегрузки (см. 8.6).
Динамические семантика
Для выполнения вызова подпрограммы имя или префикс вызова оцениваются, и каждое сопоставление параметров parameter_association оценивается (см. 6.4.1). Если используется выражение по умолчанию, предполагается неявное сопоставление параметров. Эти оценки выполняются в произвольном порядке. Затем выполняется тело подпрограммы subprogram_body, или выполняется вызов входа или защищённой подпрограммы (см. 3.9.2). Наконец, если подпрограмма завершается нормально, то после её выхода происходит необходимое присваивание формальных параметров фактическим (см. 6.4.1).
Если имя или префикс вызова подпрограммы обозначает префиксное представление (см. 4.1.3), вызов подпрограммы эквивалентен вызову базовой подпрограммы, где первый фактический параметр предоставляется префиксом префиксного представления (или атрибутом Access этого префикса, если первый формальный параметр является параметром типа указатель), а оставшиеся фактические параметры предоставляются частью параметров actual_parameter_part, если таковые имеются.
Исключение Program_Error возникает в момент вызова функции function_call, если функция завершается нормально, не выполнив оператор возврата.
Вызов функции function_call обозначает константу, как определено в 6.5; номинальный подтип константы задаётся номинальным подтипом результата функции.
Примеры
Примеры вызовов процедур:
Switch(From => X, To => Next); -- см. 6.1
Print_Header(128, Header => Title, Center => True); -- см. 6.1
Print_Header(Header => Title, Center => True, Pages => 128); -- см. 6.1
Print_Header(128, Header => Title, Center => True); -- см. 6.1
Print_Header(Header => Title, Center => True, Pages => 128); -- см. 6.1
Примеры вызовов функций:
Dot_Product(U, V) -- см. 6.1 и 6.3
Clock -- см. 9.6
F.all -- предполагается, что F имеет тип указатель на подпрограмму — см. 3.10
Clock -- см. 9.6
F.all -- предполагается, что F имеет тип указатель на подпрограмму — см. 3.10
Примеры процедур с выражениями по умолчанию:
procedure Activate(Process : in Process_Name;
After : in Process_Name := No_Process;
Wait : in Duration := 0.0;
Prior : in Boolean := False);
After : in Process_Name := No_Process;
Wait : in Duration := 0.0;
Prior : in Boolean := False);
procedure Pair(Left, Right : in Person_Name := new Person); -- см. 3.10.1
Примеры их вызовов:
Activate(X);
Activate(X, After => Y);
Activate(X, Wait => 60.0, Prior => True);
Activate(X, Y, 10.0, False);
Activate(X, After => Y);
Activate(X, Wait => 60.0, Prior => True);
Activate(X, Y, 10.0, False);
Pair;
Pair(Left => new Person, Right => new Person);
Pair(Left => new Person, Right => new Person);
ПРИМЕЧАНИЯ
7 Если выражение по умолчанию используется для двух или более параметров в нескольких parameter_specification, то выражение по умолчанию вычисляется один раз для каждого опущенного параметра. Таким образом, в вышеприведённых примерах оба вызова Pair эквивалентны.
Примеры
Примеры перегруженных подпрограмм:
procedure Put(X : in Integer);
procedure Put(X : in String);
procedure Put(X : in String);
procedure Set(Tint : in Color);
procedure Set(Signal : in Light);
procedure Set(Signal : in Light);
Примеры их вызовов:
Put(28);
Put("нет возможных неоднозначностей здесь");
Put("нет возможных неоднозначностей здесь");
Set(Tint => Red);
Set(Signal => Red);
Set(Color'(Red));
Set(Signal => Red);
Set(Color'(Red));
-- Set(Red) было бы неоднозначным, так как Red может
-- обозначать значение либо типа Color, либо типа Light
-- обозначать значение либо типа Color, либо типа Light