Примечание. Простое имя может быть заменено на расширенное имя, даже если простое имя само является префиксом именуемого компонента. Например, С.Р может быть заменено на К.С.Р, если С описано непосредственно в К.
Следующие спецификации не согласуются, так как они сформированы различными последовательностями лексем:
procedure Р (X, Y: INTEGER)
procedure? (X: INTEGER; Y: INTEGER)
procedure P (X, Y: in INTEGER)
П о д с T а и о в к а подпрограммы
Прагма INLINE используется для указания того, что желательна прямая замена телом подпрограммы каждого вызова каждой поименованной в прагме подпрограммы. Форма этой прагмы следующая:
pragma INLINE (имя {, имя});
Каждое имя — это либо имя подпрограммы, либо имя настраиваемой подпрограммы. Прагма INLINE допустима только на месте элемента описания в разделе описаний или спецификации пакета, либо после библиотечного модуля в компиляции, но до любого следующего компилируемого модуля.
Если прагма стоит на месте элемента описания, то каждое имя должно обозначать подпрограмму или настраиваемую подпрограмму, описанные раньше в виде элемента описания этого же раздела описаний или этой же спецификации пакета. Если несколько (совмещенных) подпрограмм удовлетворяют этому требованию, то прагма применяется ко всем подпрограммам. Если эта прагма стоит после данного библиотечного модуля, то в качестве ее аргумента допустимо только имя этого модуля. Если в прагме упомянуто имя настраиваемой подпрограммы, это указывает, что подстановка желательна для вызовов всех подпрограмм, являющихся конкретизацией поименованного настраиваемого модуля.
Смысл подпрограммы не изменяется прагмой INLINE. Для каждого вызова поименованных подпрограмм реализация может выполнять или игнорировать рекомендации прагмы. (Заметим, в частности, что подстановка не может быть выполнена для рекурсивных подпрограмм).
Вызовы подпрограмм
Вызов подпрограммы - это либо оператор вызова процедуры, либо вызов функции; он вызывает выполнение соответствующего тела подпрограммы. Вызов определяет связь фактических параметров, если они есть, с формальными параметрами подпрограммы.
опеоатор_вызова_процедуры : : = нмя_процедуры
[раздел—фактических—параметров];
вызов_функции :: = тля_функции [раздел_фактических— параметров] раздел_фактических_параметров : : =
(сопоставление—Параметров -[, сопоставление—параметров }) сопоставление—Параметров : : =
[формальный—параметр =>] фактический_параметр формальный—параметр : : = простоеуімя_параметра фактический—параметр : : = выражение | ямя_переменной
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
С о п о с та в л е н и я параметров
Тип каждого фактического параметра должен совпадать с типом соответствующего формального параметра.
Фактический параметр, сопоставляемый с формальным параметром вида 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).
О пу щепные параметры
Если спецификация параметра включает выражение по умолчанию для параметра вида 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 ПЕРСОНА) ;
Примечание. Если выражение по умолчанию используется для двух или более параметров в групповой спецификации параметров, то это выражение по умолчанию вычисляется один раз для каждого опущенного параметра. Поэтому в примере два вызова процедуры ПАРА эквивалентны.
Функции
Функция — это подпрограмма, которая возвращает значение (результат вызова функции). Спецификация функции начинается с зарезервированного слова function, а параметры, если они есть, должны иметь вид in (указанный явно или неявно). Операторы тела функции (исключая операторы программных модулей, вложенных в тело функции) должны содержать один или несколько операторов возврата, определяющих возвращаемое значение.
Исключение H<OGRAM_ERROR возбуждается, если выход из тела функции осуществляется не через оператор возврата. Это исключение не возбуждается, если выполнение функции прекращается в результате исключения.
Пример:
function СКАЛ_ПРОИЗВЕДЕННЕ (ЛЕВЫЙ, ПРАВЫЙ: ВЕКТОР)
return ВЕЩЕСТВ is СУММА: ВЕЩЕСТВ: = 0.0;
begin ПРОВЕРКА (ЛЕВЫЙ' FIRST = ПРАВЫЙ’ FIRST and ЛЕВЫЙ,’ LAST =
= ПРАВЫЙ’ЕАЭТ);
for К in HEBblH’RANGE loop
СУММА: = СУММА + ЛЕВЫЙ (К) * ПРАВЫЙ (К) ;
end loop;
return СУММА;
end СКАЛ_ПРОИЗВЕДЕНИЕ;
Профиль типа параметров и результата. Совмещение подпрограмм
Два раздела формальных параметров называются имеющими одинаковый профиль типа параметров тогда и только тогда, когда они имеют одинаковое число параметров, а в каждой позиции соответствующие параметры имеют один и тот же базовый тип. Подпрограмма или вход имеет одинаковый профиль типа параметров и результата с другой подпрограммой или входом тогда и только тогда, когда оба имеют одинаковый профиль типа параметров, и либо оба являются функциями с одним и тем же базовым типом результата, либо оба функциями не являются.
Один и тот же идентификатор подпрограммы или знак операции может быть использован для нескольких спецификаций подпрограмм. В этом случае идентификатор или знак операции называется совмещенным; подпрограммы, которые имеют этот идентификатор или знак операции, тоже называются совмещенными и совмещаются друг с другом. Как поясняется в разд. 8.3, если две подпрограммы совмещаются друг с другом, то одна из них может скрыть другую, только если обе подпрограммы имеют одинаковый профиль типа параметров И результата и разные зоны описания (см. 8.3, где описаны другие требования, которые должны быть удовлетворены для скрытия).
Вызов совмещенной подпрограммы неоднозначен (и поэтому неправилен) , если ее имя, число сопоставлений параметров, типы и порядок фактических параметров, имена формальных параметров (при использовании именованных сопоставлений параметров) и тип результата (для функций) не позволяют идентифицировать единственную (совмещенную) спецификацию подпрограммы.
Примеры совмещенных подпрограмм:
procedure PUT (X: INTEGER);
procedure PUT (X: STRING);
procedure SET (КОЛОРИТ: ЦВЕТ) ;
procedure SET (СИГНАЛ: СВЕТ) ;
Примеры вызовов:
PUT (28);
PUT G,здесь нет возможной неоднозначности”) ;
SET (КОЛОРИТ => КРАСНЫЙ) ;
SET (СИГНАЛ => КРАСНЫЙ);
SET (ЦВЕТ'КРАСНЫЙ);
- SET (КРАСНЫЙ) может быть неоднозначным, так как
- КРАСНЫЙ может обозначать значение типа ЦВЕТ и типа СВЕТ.
Примечание. Понятие профиля типа параметров и результата не учитывает имен параметров, их видов и подтипов, а также присутствия или отсутствия выражений по умолчанию.
Неоднозначности могут (но не обязательно) возникнуть, когда фактические параметры вызова совмещенной подпрограммы сами являются вызовами совмещенной функции, совмещенными литералами или агрегатами. Неоднозначности могут (но не обязательно) также возникнуть, когда видимы несколько совмещенных подпрограмм, принадлежащих различным пакетам. Этих неоднозначностей можно избежать несколькими способами: можно использовать квалифицированные выражения для некоторых или всех фактических параметров и результата, если он есть; имя такой подпрограммы можно задавать более точно расширенным именем; наконец, такая подпрограмма может быть переименована.
Совмещение операций
Описание функции, обозначение которой является знаком операции, используется для совмещения операций. Последовательность символов в знаке операции должна быть обозначением операций: логической, отношения, бинарной аддитивной, унарной аддитивной, мультипликативной или высшего приоритета (см. 4.5) . В качестве обозначения функции не допускаются никакие проверки вхождения, ни формы управления с промежуточной проверкой.
Спецификация подпрограммы унарной операции должна иметь один единственный параметр. Спецификация подпрограммы бинарной операции должна иметь два параметра; при каждом использовании этой операции левый операнд берется в качестве первого фактического параметра, правый операнд — в качестве второго параметра; конкретизация настройки функции, которая обозначена знаком операции, допускается, только если спецификация настраиваемой функции имеет соответствующее число параметров. Выражения по умолчанию для параметров операции недопустимы (описана ли операция явно спецификацией подпрограммы или конкретизацией настройки).