Spec-Zone.ru › GNU Fortran 14

5.1.16 Указатели Cray

Указатели Cray являются частью нестандартного расширения, которое предоставляет указатель в стиле C в Fortran. Это достигается с помощью пары переменных: целого «указателя», содержащего адрес памяти, и «указанного объекта», используемого для разыменования указателя.

Пары указатель/указанный объект объявляются в операторах следующего вида:

pointer ( <pointer> , <pointee> )

или,

pointer ( <pointer1> , <pointee1> ), ( <pointer2> , <pointee2> ), ...

Указатель — это целое число, предназначенное для хранения адреса памяти. Указанный объект может быть массивом или скаляром. Если массив с предполагаемым размером разрешен в области видимости, указанный объект может быть массивом с предполагаемым размером. То есть последняя размерность может быть оставлена не определённой с помощью *, вместо значения. Указанный объект не может быть массивом с предполагаемой формой. Для указанного объекта не выделяется память.

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

integer ipt
pointer (ipt, iarr)

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

Арифметика указателей допустима с указателями Cray, но она не такая же, как арифметика указателей C. Указатели Cray — это просто обычные целые числа, поэтому пользователь отвечает за определение того, сколько байтов нужно добавить к указателю для его инкремента. Рассмотрим следующий пример:

real target(10)
real pointee(10)
pointer (ipt, pointee)
ipt = loc (target)
ipt = ipt + 1

Последнее утверждение не устанавливает ipt в адрес target(1), как это было бы в арифметике указателей C. Добавление 1 к ipt просто добавляет один байт к адресу, хранящемуся в ipt.

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

Для получения адресов элементов это расширение предоставляет встроенную функцию LOC(). Функция LOC() эквивалентна оператору & в C, за исключением того, что адрес приводится к целому типу:

real ar(10)
pointer(ipt, arpte(10))
real arpte
ipt = loc(ar)  ! Makes arpte is an alias for ar
arpte(1) = 1.0 ! Sets ar(1) to 1.0

Указатель также может быть установлен вызовом встроенной функции MALLOC (см. MALLOC — Выделить динамическую память).

Указанные объекты Cray часто используются для алиасинга существующей переменной. Например:

integer target(10)
integer iarr(10)
pointer (ipt, iarr)
ipt = loc(target)

Пока ipt остается неизменным, iarr теперь является алиасом для target. Однако оптимизатор не будет обнаруживать этот алиасинг, поэтому небезопасно использовать iarr и target одновременно. Использование указанного объекта каким-либо способом, нарушающим правила или предположения Fortran об алиасинге, является недопустимым. Пользователь несёт ответственность за избегание этого; компилятор работает под предположением, что такой алиасинг не происходит.

Указатели Cray будут работать правильно, когда нет алиасинга (т.е. когда они используются для доступа к динамически выделенному блоку памяти), а также в любой процедуре, где указанный объект используется, но любая переменная, с которой он разделяет хранилище, не используется. Код, нарушающий эти правила, может не работать так, как предполагает пользователь. Это не ошибка оптимизатора; любой код, нарушающий правила алиасинга, является недопустимым. (Обратите внимание, что это не уникально для GNU Fortran; любой компилятор Fortran, поддерживающий указатели Cray, «неправильно» оптимизирует код с недопустимым алиасингом.)

Существует ряд ограничений на атрибуты, которые могут быть применены к указателям и указанным объектам Cray. Указанные объекты не могут иметь атрибуты ALLOCATABLE, INTENT, OPTIONAL, DUMMY, TARGET, INTRINSIC, или POINTER. Указатели не могут иметь атрибуты DIMENSION, POINTER, TARGET, ALLOCATABLE, EXTERNAL, или INTRINSIC, а также не могут быть результатами функций. Указанные объекты не могут встречаться более чем в одном операторе указателя. Указанный объект не может быть указателем. Указанные объекты не могут встречаться в операторах эквивалентности, общих или данных.

Указатель Cray также может указывать на функцию или подпрограмму. Например, следующий фрагмент является допустимым:

implicit none
external sub
pointer (subptr,subpte)
external subpte
subptr = loc(sub)
call subpte()
[...]
subroutine sub
[...]
end subroutine sub

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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gfortran/Cray-pointers.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API