Проверьте, может ли массив размещаться в фортране

В фортране можно проверить, выделен ли выделяемый массив, с помощью оператора allocated:

program test_allocated
  integer :: i = 4
  real(4), allocatable :: x(:)

  print *, 'before allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)

  allocate(x(i))
  print *, 'after allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)

end program test_allocated

Однако возможно ли как-то проверить, был ли обычный массив объявлен как распределяемый? Следующий код

program test_allocated
  integer :: i = 4
  real(4), allocatable :: x(:)
  real(4)::y
  print *, 'before allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)
  print *, 'allocated(y)'
  print *, allocated(y)
  allocate(x(i))
  print *, 'after allocation of x'
  print *, 'allocated(x)'
  print *, allocated(x)
  print *, 'allocated(y)'
  print *, allocated(y)
end program test_allocated

выдает ошибку

D:\TEMP\FortranTest\ifort>ifort test.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Inte
l(R) 64, Version 13.0.1.119 Build 20121008
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.

test.f90(9): error #6547: The ARRAY argument of the ALLOCATED inquiry intrinsic
function shall be an allocatable array.   [Y]
  print *, allocated(y)
---------------------^
test.f90(15): error #6547: The ARRAY argument of the ALLOCATED inquiry intrinsic
 function shall be an allocatable array.   [Y]
  print *, allocated(y)
---------------------^
compilation aborted for test.f90 (code 1)

Возможно, существует другой оператор или метод для выяснения природы массива?


person user32882    schedule 27.08.2017    source источник
comment
В стандартном Фортране этого сделать нельзя. Возможно, если вы объясните, почему вы хотите проверить статус распределения нераспределяемых сущностей, кто-нибудь сможет найти разумное решение этой проблемы.   -  person High Performance Mark    schedule 27.08.2017
comment
Fortran является статическим языком в том смысле, что компилятор знает, является ли переменная фиксированным массивом или размещаемым массивом. Но в Фортране нет отражения, где эта информация доступна самой программе (в отличие, например, от C#).   -  person John Alexiou    schedule 27.08.2017
comment
Возможный дубликат представления внутренней памяти Fortran, выделяемого   -  person Rodrigo Rodrigues    schedule 19.10.2018


Ответы (1)


Некоторые компиляторы хранят метаданные массива в дескрипторе допингового массива, включая такие атрибуты, как возможность размещения, смежность, размер хранилища элементов, статус определения, если это указатель... Они необходимы внутри языка для проверки соответствия интерфейсов при вызовах конкретных процедур.

Таким образом, технически возможно проверять такого рода метаинформацию, но это также вряд ли полезно. Опять же, Фортран статически типизирован, и компилятор может выполнять все эти проверки во время компиляции.

Более того, язык разработан таким образом, что вы можете обрабатывать выделение для переменной (или фиктивного аргумента) только тогда, когда вы явно объявили его доступным для размещения (или указателем). Во всех остальных случаях вы можете использовать массив, не беспокоясь о том, как он был выделен.

См. эту ветку форума:

После того, как вы выделили выделяемый массив, он теперь является таким же хорошим массивом, как и любой другой, и его можно передавать в качестве фактического аргумента процедурам (или функциям C), которым даже не нужно знать, что он может быть размещен. Я мог бы добавить, что то же самое относится и к массивам указателей, хотя в этом случае есть одно небольшое предостережение (включающее возможность того, что массив указателей может указывать на несмежный фрагмент).

В вашем конкретном случае вы пытаетесь использовать встроенную функцию allocated с нераспределяемым массивом y, что приводит к ошибке. Вам не нужно проверять, является ли массив доступным для размещения, прежде чем использовать для него эту функцию, вам просто нужно знать, что, если вы явно не объявили его как allocatable (как вы сделали с x), это не так. .

Точно так же, если вы хотите управлять выделением переменной внутри функции или подпрограммы, вам просто нужно объявить фиктивный аргумент как выделяемый, и вам гарантируется, что процедура будет принимать только размещаемые переменные (то же самое с указателями).


Если по какой-либо причине у вас есть веские причины использовать внутреннее представление переменных, и вы знаете, что делаете, вы можете обратиться к этот ответ от @VladmirF на другой вопрос или погрузитесь в справочное руководство вашего конкретного компилятора. Кроме того, в последних версиях стандарта указывается стандартизированный дескриптор массива, обеспечивающий взаимодействие с кодом C.


Наконец, поскольку вы отметили Intel в этом вопросе, я укажу вам на справочник по компилятору Intel. по этому вопросу, где вы можете увидеть, что:

Недостатком использования дескрипторов массива является то, что это может увеличить вероятность ошибок. Кроме того, соответствующий код не является переносимым. Конкретно:

Если дескриптор определен неправильно, программа может получить доступ к неправильному адресу памяти, что может привести к общему сбою защиты.

Форматы дескрипторов массивов специфичны для каждого компилятора Fortran. Код, использующий дескрипторы массива, нельзя перенести на другие компиляторы или платформы.

Формат дескриптора массива может измениться в будущем.

Если дескриптор был создан компилятором, он не может быть изменен пользователем. Изменение полей существующих дескрипторов является незаконным.

Компоненты текущего дескриптора массива Intel® Fortran в системах, использующих архитектуру IA-32, следующие:

Байты с 0 по 3 содержат базовый адрес.

(...)

Байты с 12 по 15 содержат набор флагов, используемых для хранения информации о массиве. Это включает:

бит 1 (0x01): массив определен — устанавливается, если массив был определен (выделена память).

(...)

бит 8 (0x80): устанавливается, если указанный массив является ALLOCATABLE.

Остальные биты зарезервированы.

person Rodrigo Rodrigues    schedule 19.10.2018