Spec-Zone.ru › GNU Fortran 12

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

Spec-Zone.ru

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