Примечание. Простое имя может быть заменено на расширенное имя, даже если простое имя само является префиксом именуемого компонента. Например, С.Р мо­жет быть заменено на К.С.Р, если С описано непосредственно в К.

Следующие спецификации не согласуются, так как они сформированы различны­ми последовательностями лексем:

procedure Р (X, Y: INTEGER)

procedure? (X: INTEGER; Y: INTEGER)

procedure P (X, Y: in INTEGER)

  1. П о д с T а и о в к а подпрограммы

Прагма INLINE используется для указания того, что желательна прямая замена телом подпрограммы каждого вызова каждой поименованной в прагме подпрограммы. Форма этой прагмы следующая:

pragma INLINE (имя {, имя});

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

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

Смысл подпрограммы не изменяется прагмой INLINE. Для каждого вызова поименованных подпрограмм реализация может выполнять или иг­норировать рекомендации прагмы. (Заметим, в частности, что подстановка не может быть выполнена для рекурсивных подпрограмм).

  1. Вызовы подпрограмм

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

опеоатор_вызова_процедуры : : = нмя_процедуры

[раздел—фактических—параметров];

вызов_функции :: = тля_функции [раздел_фактических— параметров] раздел_фактических_параметров : : =

(сопоставление—Параметров -[, сопоставление—параметров }) сопоставление—Параметров : : =

[формальный—параметр =>] фактический_параметр формальный—параметр : : = простоеуімя_параметра фактический—параметр : : = выражение | ямя_переменной

I обозначение_типа (имя_переменнои)

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

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

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

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

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

ОБХОД-ДЕРЕВА; -см. 6.1

УПРАВЛЕНИЕ-ТАБЛИЦЕЙ.ВСТАВКА (Е) ; - - см. 7.5

ПЕЧАТЬ-ЗАГОЛОВКА (128, ТИТУЛ, TRUE); - - см. 6.1

ПЕРЕКЛЮЧАТЕЛЬ (ИЗ => X, В => СЛЕДУЮЩИЙ; - - см. 6.1

ПЕЧАТЬ-ЗАГОЛОВКА (128, ЗАГОЛОВОК => ТИТУЛ, ЦЕНТР => TRUE);

- - см. 6.1

ПЕЧАТЬ-ЗАГОЛОВКА (ЗАГОЛОВОК => ТИТУЛ, ЦЕНТР => TRUE, СТРАНИЦЫ => 128) ; - - см. 6.1

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

СКАЛ_ПРОИЗВЕДЕНИЕ (А, В) - - см. 6.1 и 6.5

CLOCK--см. 9.6

  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).

  1. О пу щепные параметры

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

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

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

procedure АКТИВИЗИРОВАТЬ (ПРОЦЕСС: in ИМЯ_ПРОЦЕССА;

ПОСЛЕ: in ИМЯ_ПРОЦЕССА: - НЕТ_ПРОЦЕССА;

ЖДАТЬ: in DURATION: = 0.0;

ПРИОР: in BOOLEAN: = FALSE);

procedure ПАРА (ЛЕВЫЙ, ПРАВЫЙ: ИМЯ_ПЕРСОНЫ: = new ПЕРСОНА);

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

АКТИВИЗИРОВАТЬ (X);

АКТИВИЗИРОВАТЬ (X, ПОСЛЕ => Y) ;

АКТИВИЗИРОВАТЬ (X, ЖДАТЬ => 60.0, ПРИОР => TRUE);

’ АКТИВИЗИРОВАТЬ (X, Y, 10.0, FALSE);

ПАРА;

ПАРА (ЛЕВЫЙ => new ПЕРСОНА, ПРАВЫЙ => new ПЕРСОНА) ;

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

  1. Функции

Функция — это подпрограмма, которая возвращает значение (результат вызова функции). Спецификация функции начинается с зарезервированно­го слова function, а параметры, если они есть, должны иметь вид in (указан­ный явно или неявно). Операторы тела функции (исключая операторы про­граммных модулей, вложенных в тело функции) должны содержать один или несколько операторов возврата, определяющих возвращаемое значение.

Исключение H<OGRAM_ERROR возбуждается, если выход из тела функции осуществляется не через оператор возврата. Это исключение не возбуждается, если выполнение функции прекращается в результате исклю­чения.

Пример:

function СКАЛ_ПРОИЗВЕДЕННЕ (ЛЕВЫЙ, ПРАВЫЙ: ВЕКТОР)

return ВЕЩЕСТВ is СУММА: ВЕЩЕСТВ: = 0.0;

begin ПРОВЕРКА (ЛЕВЫЙ' FIRST = ПРАВЫЙ’ FIRST and ЛЕВЫЙ,’ LAST =

= ПРАВЫЙ’ЕАЭТ);

for К in HEBblH’RANGE loop

СУММА: = СУММА + ЛЕВЫЙ (К) * ПРАВЫЙ (К) ;

end loop;

return СУММА;

end СКАЛ_ПРОИЗВЕДЕНИЕ;

  1. Профиль типа параметров и результата. Совмещение подпрограмм

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

Один и тот же идентификатор подпрограммы или знак операции может быть использован для нескольких спецификаций подпрограмм. В этом слу­чае идентификатор или знак операции называется совмещенным; подпро­граммы, которые имеют этот идентификатор или знак операции, тоже назы­ваются совмещенными и совмещаются друг с другом. Как поясняется в разд. 8.3, если две подпрограммы совмещаются друг с другом, то одна из них может скрыть другую, только если обе подпрограммы имеют одинако­вый профиль типа параметров И результата и разные зоны описания (см. 8.3, где описаны другие требования, которые должны быть удовлетворены для скрытия).

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

Примеры совмещенных подпрограмм:

procedure PUT (X: INTEGER);

procedure PUT (X: STRING);

procedure SET (КОЛОРИТ: ЦВЕТ) ;

procedure SET (СИГНАЛ: СВЕТ) ;

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

PUT (28);

PUT G,здесь нет возможной неоднозначности”) ;

SET (КОЛОРИТ => КРАСНЫЙ) ;

SET (СИГНАЛ => КРАСНЫЙ);

SET (ЦВЕТ'КРАСНЫЙ);

  • - SET (КРАСНЫЙ) может быть неоднозначным, так как

  • - КРАСНЫЙ может обозначать значение типа ЦВЕТ и типа СВЕТ.

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

Неоднозначности могут (но не обязательно) возникнуть, когда фактические пара­метры вызова совмещенной подпрограммы сами являются вызовами совмещенной функции, совмещенными литералами или агрегатами. Неоднозначности могут (но не обязательно) также возникнуть, когда видимы несколько совмещенных подпро­грамм, принадлежащих различным пакетам. Этих неоднозначностей можно избежать несколькими способами: можно использовать квалифицированные выражения для некоторых или всех фактических параметров и результата, если он есть; имя такой подпрограммы можно задавать более точно расширенным именем; наконец, такая подпрограмма может быть переименована.

  1. Совмещение операций

Описание функции, обозначение которой является знаком операции, используется для совмещения операций. Последовательность символов в знаке операции должна быть обозначением операций: логической, отноше­ния, бинарной аддитивной, унарной аддитивной, мультипликативной или высшего приоритета (см. 4.5) . В качестве обозначения функции не допус­каются никакие проверки вхождения, ни формы управления с промежуточ­ной проверкой.

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