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