Говорят, что значение объекта читается, когда это значение вычисляется; оно также читается, когда читается одна из его подкомпонент. Говорят, что значение переменной изменяется, когда выполняется присваивание этой переменной, а также (косвенно) когда эта переменная используется в качестве фактического параметра оператора вызова подпрограммы или оператора вызова входа, которые изменяют ее значение; говорят также, что оно изменяется, когда изменяется одна из его подкомпонент.
Формальный параметр подпрограммы бывает одного из следующих трех видов:
in |
Формальный параметр — константа, разрешается только чтение значения соответствующего фактического параметра. |
in out |
Формальный параметр — переменная, разрешается как чтение, так и изменение значения соответствующего фактического параметра. |
out |
Формальный параметр — переменная, разрешается изменение значения соответствующего фактического параметра. Значение скалярного параметра, которое не изменяется при вызове, после возврата не определено; то же самое имеет место для значения скалярной подкомпоненты, отличной от дискриминанта. Допускается чтение границ и дискриминантов формального параметра и его подкомпонент; никакое другое чтение не допускается. |
Для скалярного параметра такой эффект достигается копированием: в начале каждого вызова значение фактического параметра, соответствующего формальному параметру вида inили in out, копируется в этом формальном параметре (прямое копирование); затем после нормального окончания тела подпрограммы значение формального параметра вида in out или out копируется обратно в соответствующем фактическом параметре (обратное копирование). Для параметра ссылочного типа прямое копирование используется для всех трех видов, а обратное — для видов in out и out.
Для параметров индексируемого, именуемого или задачного типов реализация может достигнуть такого же эффекта копированием, как и для скалярных типов. Кроме того, если копирование используется для параметра вида out, то прямое копирование требуется по крайней мере для границ и дискриминантов фактического параметра и его подкомпонент, а также для каждой подкомпоненты ссылочного типа. Другой вариант — вызов ссылкой, когда каждое использование формального параметра (чтение или изменение его значения) рассматривается как использование соответствующего фактического параметра при выполнении вызова подпрограммы. В языке не определяется, какой из этих двух механизмов следует применять для передачи параметров; не определяется также, что различные вызовы одной и той же подпрограммы должны использовать один и тот же механизм. Выполнение программы ошибочно, если ее результат зависит от механизма, выбираемого реализацией.
Для параметра личного типа вышеуказанный эффект достигается по правилу, которое применяется к соответствующему полному описанию типа.
В теле подпрограммы формальный параметр отвечает любому ограничению, вытекающему из обозначения типа, данного в спецификации этого параметра. В качестве границ формального параметра неограниченного индексируемого типа берутся границы фактического параметра (см. 3.6.2). Для формального параметра, описание которого задает неограниченный (личный или именуемый) тип с дискриминантами, дискриминанты этого формального параметра инициализируются значениями соответствующих дискриминантов фактического параметра; формальный параметр не ограничен тогда и только тогда, когда его вид in out или out и имя переменной, являющейся фактическим параметром, обозначает неограниченную переменную (см. 3.7.1 и 6.4.1).
Если фактический параметр вызова подпрограммы является подкомпонентой, которая зависит от дискриминантов переменной неограниченного именуемого типа, то выполнение вызова ошибочно, если значение любого дискриминанта переменной изменяется при этом выполнении; это правило не применяется, если вид параметра in и тип подкомпоненты — скалярный тип или ссылочный тип.
Примечание. Из правил передачи параметров индексируемого и именуемого типов следует:
• Если выполнение подпрограммы прекращено в результате исключения, конечное значение фактического параметра такого типа может быть либо тем же, что и до вызова, либо значением, присвоенным формальному параметру во время выполнения подпрограммы.
• Если доступ ко всем фактическим параметрам такого типа осуществляется одним способом, то результат вызова подпрограммы (при отсутствии исключения) не зависит от того, использует ли реализация для передачи параметров копирование. Если, однако, доступ к фактическому параметру осуществляется несколькими способами (например, если глобальная переменная или другой формальный параметр ссылается на один и тот же фактический параметр), то значение формального параметра после изменения фактического способом, отличным от изменения формального, неопределенно. Программа, использующая такое неопределенное значение, является ошибочной.
Такие же виды параметров определены и для формальных параметров входов (см. 9.5) с тем же смыслом, что и для подпрограмм. Для формальных параметров настройки определены другие виды параметров (см. 12.1.1).
Для всех видов справедливо, что если фактический параметр указывает задачу, то соответствующий формальный параметр указывает ту же задачу; то же самое имеет место для подкомпоненты фактического параметра и соответствующей подкомпоненты формального параметра.
Ссылки: вид 6.1, выражение 4.4, вычисление 4.5, глобальный 8.1, граница массива 3.6.1, дискриминант 3.7.1, зависеть от дискриминанта 3.7.1, задача 9, задачный тип 9.2, именуемый тип 3.7, индексируемый тип 3.6, исключение 11, личный тип 7.4, неограниченная переменная 3.2.1, неограниченный индексируемый тип 3.6, неограниченный тип с дискриминантами 3.7.1, обозначение типа 3.3.2, объект 3.2, ограничение 3.3, оператор вызова входа 9.5, операторвызова подпрограммы 6.4, ошибочный 1.6, переменная 3.2.1, подкомпонента 3.3, присваивание 5.2, скалярный тип 3.5, спецификация параметра 6.1, ссылочное значение null 3.8, ссылочный тип 3.8, тело подпрограммы 6.3, фактический параметр 6.4.1, формальный параметр 6.1, формальный параметр настройки 12.1.