6.1.14 Указатели 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-9.3.0/gfortran/Cray-pointers.html