6.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
Указатель может изменяться в ходе выполнения программы, и это изменит местоположение, на которое указывает указаваемая переменная. Однако при передаче указаваемой переменной в качестве аргументов она обрабатывается как обычная переменная в вызываемой функции. Последующие изменения указателя не изменят базовый адрес массива, который был передан.
Далее: CONVERT specifier, Предыдущее: Преобразование символьных данных, Вверх: Расширения, реализованные в GNU Fortran [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gfortran/Cray-pointers.html