6.4. ВЫЗОВЫ ПОДПРОГРАММ

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

оператор-вызова-процедуры ::=    имя-процедуры [раздел - фактических - параметров]; вызов функции ::=     имя-функции [раздел - фактических - параметров]раздел-фактических-параметров ::=    (сопоставление-параметров {, сопоставление-параметров})сопоставление - параметров ::=    [формальный-параметр =>] фактический-параметрформальный-параметр ::= простое-имя-параметрафактический-параметр ::= выражение | имя-переменной    | обозначение-типа (имя-переменной)

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

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

Для каждого формального параметра подпрограммы вызов подпрограммы должен задавать точно один соответствующий фактический параметр. Этот фактический параметр определяется либо явно сопоставлением параметра, либо в отсутствие такого сопоставления выражением по умолчанию (см. 6.4.2).

Сопоставления параметров вызова подпрограммы вычисляются в некотором порядке, не определенном в языке. Аналогично правила языка не определяют, в каком порядке значения параметров вида in out или out копируются обратно в соответствующих фактических параметрах (если это делается).

Примеры вызовов процедур:

TRAVERSE_TREE;                                                   -— СМ. 6.1 TABLE_MANAGER.INSERT(E);                                         -— 7.5 PRINT_HEADER(128, TITLE, TRUE);                                  —- см. 6.1SWITCH(FROM => X, TO => NEXT);                                   -— CM. 6.1 PRINT_HEADER(128, HEADER => TITLE, CENTER => TRUE);              -— CM. 6.1 PRINT_HEADER(HEADER => TITLE, CENTER => TRUE, PAGES => 128);     -— CM. 6.1

Примеры вызовов функций:

DOTPRODUCT(U, V)     -— см. 6.1 и 6.5 CLOCK                —- см. 9.6

Ссылки: выражение 4.4, выражение по умолчанию для формального параметра 6.1, имя 4.1, обозначение типа 3.3.2, ошибочный 1.6, переменная 3.2.1, подпрограмма 6, простое имя 4.1, раздел формальных параметров 6.1, формальный параметр 6.1.

6.4.1. СОПОСТАВЛЕНИЯ ПАРАМЕТРОВ

Тип каждого фактического параметра должен совпадать с типом соответствующего формального параметра.

Фактический параметр, сопоставляемый с формальным параметром вида in, должен быть выражением; оно вычисляется до вызова.

Фактический параметр, сопоставляемый с формальным параметром вида in out или out, должен быть либо именем переменной, либо иметь форму преобразования типа с аргументом^ являющимся именем переменной. В любом случае для параметра вида in out переменная не должна быть формальным параметром вида out или подкомпонентой такого параметра. Для фактического параметра, который имеет форму преобразования типа, обозначение типа должно быть согласовано (см. 6.3.1) с обозначением типа формального параметра; допустимый операнд и целевой тип такие же, как и для преобразования типа (см. 4.6).

Данное для фактического параметра вида in out или out имя переменной вычисляется до вызова. Если фактический параметр имеет форму преобразования типа, то перед вызовом для параметра вида in out переменная преобразуется к заданному типу; после (нормального) окончания тела подпрограммы формальные параметры вида in out или out преобразуются обратно в тип переменной. (Тип преобразования должен быть тем же, что и у формального параметра.)

Для параметров скалярного и ссылочного типов проверяются следующие ограничения:

• Перед вызовом для параметра вида in или in out проверяется принадлежность фактического параметра подтипу формального параметра.

• После (нормального) окончания тела подпрограммы для параметра вида in out или out проверяется принадлежность значения формального параметра подтипу фактического параметра. В случае преобразования типа значение формального параметра преобразуется обратно и проверяется результат преобразования.

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

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

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

Примечание. Если обозначение типа формального параметра задает ограниченный подтип, то для индексируемых типов и типов с дискриминантами достаточно проверки перед вызовом (проверка после возврата была бы избыточной), так как ни границы массива, ни дискриминанты не могут быть изменены.

Если это обозначение типа задает неограниченный индексируемый тип, то формальный параметр ограничен границами соответствующего фактического параметра и никакой проверки не требуется (ни до вызова, ни после возврата, см. 3.6.1). Аналогично не требуется никакой проверки, если обозначение типа обозначает неограниченный тип с дискриминантами, так как формальный параметр ограничен точно так же, как соответствующий фактический параметр (см. 3.7.1).

Ссылки: вид 6.1, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, вычисление имени 4.1, граница массива 3.6, дискриминант 3.7.1, имя 4.1, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, неограниченный индексируемый тип 3.6, неограниченный тип с дискриминантами 3.7.1, неопределенное значение 3.2.1, обозначение типа 3.8.2, ограничение 3.3, ограниченный подтип 3.3, ошибочный 1.6, переменная 3.2.1, пбдтип 3.3, преобразование типа 4.6, согласованный 6.3.1, сопоставление параметров 6.4, тип 3.3, фактический параметр 6.4, формальный параметр 6.1.

6.4.2. ОПУЩЕННЫЕ ПАРАМЕТРЫ

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

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

Примеры процедур со значениями по умолчанию:

procedure ACTIVATE) PROCESS : in PROCESSNAME;    AFTER : in PROCESSNAME := NOPROCESS;    WAIT : in DURATION := 0.0;    PRIOR : in BOOLEAN := FALSE);procedure PAIR(LEPT, RIGHT : PERSONNAME := new PERSON);

Примеры их вызовов:

ACTIVATE(X); 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 эквивалентны.

Ссылки: вид 6.1, вызов подпрограммы 6.4, выражение по умолчанию для формального параметра 6.1, вычисление 4.5, именованное сопоставление параметров 6.4, позиционное сопоставление параметров 6.4, спецификация параметра 6.1, фактический параметр 6.1.