Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

О. В. Бартеньев. Современный ФОРТРАН

8.21. Атрибут AUTOMATIC

В CVF и FPS по умолчанию переменные являются в большинстве случаев статическими, т. е. под них всегда выделена память и они размещены в памяти статически (адрес размещения статической переменной не меняется в процессе выполнения программы). Переменная называется автоматической, если память под эту переменную выделяется по необходимости. Размещение автоматических переменных выполняется в стеке. Примерами автоматических объектов являются объявляемые в процедуре автоматические массивы и строки. Однако в процедуре и модуле можно сделать переменную автоматической, присвоив ей атрибут AUTOMATIC. Атрибут AUTOMATIC является расширением над стандартом Фортрана и может быть задан в отдельном операторе и при объявлении типа:

АUTOMATIC [список имен переменных]

type-spec, АUTOMATIC [, атрибуты] :: список имен переменных

Автоматические переменные прекращают существование после выполнения операторов RETURN или END. Таким образом, их значения при следующем вызове процедуры могут отличаться от тех, которые они получили ранее.

Если оператор AUTOMATIC задан без списка имен, то все переменные внутри блока видимости, которые могут иметь атрибут AUTOMATIC, будут неявно объявлены автоматическими.

В операторе AUTOMATIC не могут появляться:

имена и объекты common-блоков;

переменные, имеющие атрибут SAVE;

переменные с атрибутами ALLOCATABLE или EXTERNAL;

формальные параметры и имена процедур.

Переменная, которой явно присвоен атрибут AUTOMATIC, не может

быть инициализирована в операторе DATA или в операторе объявления типа. Переменные, неявно ставшие автоматическими и появившиеся в операторе DATA или инициализированные в операторе объявления типа, получат атрибут SAVE и будут помещены в статическую память.

Переменная не может появляться в операторе AUTOMATIC более одного раза.

Пример:

 

call atav(2, 3)

 

call atav(4, 5)

 

end

 

subroutine atav (m, n)

 

automatic

! Переменные объявляются автоматическими неявно

278

 

8. Программные единицы

integer :: m, n, a, b = 2

! Переменная b является статической,

print *, 'b = ', b

a = m

! поэтому сохраняет полученное значение

b = n

! при повторном вызове

end

! Переменная a является автоматической

Результат:

b = 2 b = 3

8.22. Атрибут SAVE

Существующая в процедуре или модуле переменная будет сохранять свое значение, статус определенности, статус ассоциирования (для ссылок) и статус размещения (в случае размещаемых массивов) после выполнения оператора RETURN или END, если она имеет атрибут SAVE. В CVF и FPS все переменные (кроме объектов с атрибутом ALLOCATABLE или POINTER и автоматических объектов) по умолчанию имеют такой атрибут. Поэтому объявление переменной с атрибутом SAVE выполняется для создания программ, переносимых на другие платформы или в том случае, если переменные процедуры или модуля неявно получили атрибут AUTOMATIC. Атрибут SAVE задается отдельным оператором или при объявлении типа:

SAVE [[::] список объектов]

type-spec, SAVE [, атрибуты] :: список объектов

Список объектов может включать имена переменных и common-блоков. Последние при задании обрамляются слешами. Один и тот же объект не может дважды появляться в операторе SAVE.

Если оператор SAVE задан без списка объектов, то все объекты программной единицы, которые могут иметь атрибут SAVE, получают этот атрибут.

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

Атрибут SAVE не может быть задан:

переменным, помещенным в common-блок;

формальным параметрам процедур;

именам процедур и результирующей переменной функции;

автоматическим массивам и строкам (разд. 4.8.3);

объектам, явно получившим атрибут AUTOMATIC.

Пример:

279

О. В. Бартеньев. Современный ФОРТРАН

subroutine shosa( ) real da, a, dum

common /bz/ da, a, dum(10) real(8), save :: x, y

save /bz/

8.23. Атрибут STATIC

Имеющие атрибут STATIC переменные (в процедуре или модуле) сохраняются в (статической) памяти в течение всего времени выполнения программы. Атрибут является расширением над стандартом Фортрана и эквивалентен ранее приведенному атрибуту SAVE и атрибуту STATIC языка СИ. Значения статических переменных сохраняются после выполнения оператора RETURN или END. Напомним, что в CVF и FPS по умолчанию переменные (кроме динамических) размещены в статической памяти. Для изменения правил умолчания используются атрибуты ALLOCATABLE, AUTOMATIC и POINTER. Атрибут STATIC может быть задан в двух формах:

STATIC [[::] список объектов]

type-spec, STATIC [, атрибуты] :: список объектов

Список объектов может включать имена переменных и common-блоков. Имена последних при включении их в список объектов оператора STATIC обрамляются слешами.

Пример:

integer :: ng = -1

! Цикл завершается при ng = 0

do while(ng /= 0)

call sub1(ng, ng + ng)

 

print *, 'Enter integer non zero value to continue or zero to quit'

read *, ng

 

end do

 

contains

subroutine sub1(iold, inew) integer, intent(inout) :: iold

integer, static :: n2

! При каждом вызове n2 = -1

integer, automatic :: n3

 

integer, intent(in) :: inew

if(iold == -1) then

 

n2 = iold

! Значение n3 определено только при ng = -1

n3 = iold

end if

 

print *, 'new: ', inew, '

n2: ', n2, ' n3: ', n3

end subroutine

 

end

 

280

8. Программные единицы

8.24. Атрибут VOLATILE

Атрибут может быть задан только в CVF и является расширением над стандартом Фортрана. Атрибут указывает компилятору, что значение объекта непредсказуемо. Объект, обладающий атрибутом VOLATILE, не будет оптимизироваться в процесс компиляции. Как и другие, атрибут может быть задан в двух формах:

VOLATILE список объектов

type-spec, VOLATILE [, атрибуты] :: список объектов

Список объектов может включать имена переменных и common-блоков. Имена последних при включении их в список объектов оператора VOLATILE обрамляются слешами.

Переменная или common-блок должны объявляться VOLATILE, если способ их определения неочевиден для компилятора. Например, если операционная система размещает переменную в разделяемой памяти, с тем чтобы ее могла использовать другая программа, которая может в том числе и изменить значение переменной, или в случае ассоциирования памяти посредством оператора EQUIVALENCE.

Если составной объект (массив, производный тип) объявляется VOLATILE, то каждый его элемент получает этот атрибут. Аналогично если com- mon-блок объявляется VOLATILE, то этим атрибутом обладает каждый его элемент.

Атрибут VOLATILE не может быть задан процедуре, результату функции и namelist-группе.

Пример:

logical(kind = 1) ipi(4) integer(kind = 4) a, b, c, d, e, ilook integer(kind = 4) p1, p2, p3, p4 common /blk1/ a, b, c

volatile /blk1/, d, e equivalence(ilook, ipi) equivalence(a, p1) equivalence(p1, p4)

Именованный common-блок blk1, переменные d и e объявляются VOLATILE явно. Поведение переменных p1 и p4 в результате их ассоциирования по памяти (прямого и непрямого) с volatile-переменной a зависит от a.

8.25. Чистые процедуры

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

program side_effect

real(4) :: dist, d, p = 3.0, q = 4.0, r = 5.0

281

О. В. Бартеньев. Современный ФОРТРАН

d = max(dist(p, q), dist(q, r))

print *, d ! 7.071068 end program side_effect

function dist(p, q) real(4) :: dist, p, q

dist = sqrt(p * p + q * q)

q = dist ! Изменение q - побочный эффект end function dist

Суть его в том, что функция dist переопределяет значение параметра q. А это означает, что второй вызов функции dist при вычислении d, выполняется при q, равном 5.0, вместо ожидаемого первоначального значения q = 4.0. Такие эффекты запрещены стандартом и должны отслеживаться и устраняться программистом.

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

[type-spec] PURE SUBROUTINE | FUNCTION name

&

[RESULT (resultname)]

 

или

 

PURE [type-spec] SUBROUTINE | FUNCTION name

&

[RESULT (resultname)]

 

type-spec - тип результирующей переменной функции. name - имя процедуры.

resultname - имя результирующей переменной функции. Чистая процедура характеризуется тем, что:

функция возвращает значение и не меняет ниодного из своих параметров;

подпрограмма изменяет только те параметры, которые имеют вид связи

INTENT(OUT) и INTENT(INOUT).

По умолчанию чистыми являются:

все встроенные функции и встроенная подпрограмма MVBITS;

процедуры библиотеки высокоскоростного Фортрана, применяемого для параллельных вычислений под Юниксом.

Вчистых процедурах все формальные параметры, кроме формальных процедур и ссылок, должны иметь вид связи:

для функций - только INTENT(IN);

для подпрограмм - любой: INTENT(IN, или OUT, или INOUT).

Никакие локальные переменные чистой процедуры, в том числе и относящиеся к внутренним процедурам, не должны:

обладать атрибутом SAVE;

быть инициализированными в операторах объявления или DATA. В чистых процедурах имеются ограничения на использование:

282

8. Программные единицы

глобальных переменных;

формальных параметров с видом связи INTENT(IN) или с необъявленным видом связи;

объектов, ассоциируемых по памяти с какими-либо глобальными переменными.

Ограничения таковы: перечисленные объекты не должны использоваться:

1)в случаях, когда возможно изменение их значения. Это может произойти, если переменная является:

левой частью оператора присваивания или прикрепления ссылки (если объект является ссылкой);

фактическим параметром, ассоциированным с формальным параметром с видом связи INTENT(OUT или INOUT) или обладающим атрибутом

POINTER;

индексной переменной операторов DO, FORALL или встроенного DOцикла;

переменной оператора ASSIGN;

элементом списка ввода оператора READ;

именем внутреннего файла оператора WRITE;

объектом операторов ALLOCATE, DEALLOCATE или NULLIFY;

спецификатором IOSTAT или SIZE операторов В/В или STAT

операторов ALLOCATE и DEALLOCATE;

2)в создании ссылки, например в качестве адресата или в качестве элемента правой части оператора присваивания переменной производного типа, если он имеет ссылочный компонент на любом из его уровней.

Чистые процедуры не должны содержать:

операторы В/В во внешние файлы или устройства;

операторы PAUSE и STOP.

Чистые процедуры предназначены для вызова в тех случаях, когда вызов

иных, не владеющих ключевым словом PURE процедур недопустим:

в операторе FORALL или его выражении-маске;

из другой чистой процедуры.

Также только чистую процедуру можно использовать в качестве параметра другой чистой процедуры.

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

Пример:

pure function decr(k, m) real(4) :: decr

283