Spec-Zone.ru › GNU Fortran 7

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-7.2.0/gfortran/Cray-pointers.html

Spec-Zone.ru

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