Ошибка в объявлении производного типа: переменная в (1) в этом контексте должна быть постоянной

У меня есть производный тип, объявленный в таком модуле:

MODULE dmotifs
TYPE :: PRM
    INTEGER, PRIVATE :: nsp=4,nrx=8,maxprx=4
    REAL, PRIVATE :: cref=1e-6,tref=1
    REAL, DIMENSION(nrx,maxprx) :: k
    REAL :: input
END TYPE PRM

CONTAINS

SUBROUTINE unreg(y,param,r,s)

    TYPE(PRM), INTENT(IN) :: param
    REAL, DIMENSION(param%nsp), INTENT(IN) :: y
    INTEGER, DIMENSION(param%nsp,param%nrx), INTENT(OUT) :: s=0
    REAL, DIMENSION(param%nrx,1), INTENT(OUT) :: r=0
    REAL :: mOut, mCtrl, pOut, pCtrl
    mOut=y(ind_mOut)
    mCtrl=y(ind_mCtrl) 
    pOut=y(ind_pOut)
    pCtrl=y(ind_pCtrl)

    ! <some operations on "r" and "s">
    RETURN 

END SUBROUTINE unreg
END MODULE dmotifs

При компиляции я получаю эту ошибку:

Error: Variable 'nrx' at (1) in this context must be constant

Что означает выражение «должно быть константой»; должен ли он быть неизменным во время компиляции, т.е. как ПАРАМЕТР?

Но есть еще одна проблема: я не могу объявлять ПАРАМЕТРЫ в производных типах. Как бороться с этой ошибкой? Будет ли удаление этих объектов из производного типа и превращение их в ПАРАМЕТРЫ единственным вариантом?

Самое главное, я хочу понять, почему это происходит.

Я компилировал с помощью gfortran: gfortran -Wall -c "dmotifs.f90"


person WYSIWYG    schedule 12.02.2015    source источник
comment
@VladimirF Вся часть огромна. Он содержит подпрограммы, использующие этот тип.   -  person WYSIWYG    schedule 12.02.2015
comment
Вы могли бы легко извлечь определение в отдельный исходный файл, чтобы показать, что проблема именно здесь. См. stackoverflow.com/help/mcve. Но на самом деле этого было более чем достаточно, чтобы включить полное сообщение об ошибке, включая< /i> 1 указывает на оскорбительную строку. Сначала я не заметил другого появления nrx.   -  person Vladimir F    schedule 12.02.2015


Ответы (1)


Да. Для объявления массива явной формы в непараметризованном производном типе требуется константное выражение. Вы могли бы либо

  • сделать k allocatable,dimension(:,:) (и (отменить) выделение) или
  • сделайте nrx и maxprx глобальными/модульными константами (или замените их сразу).

Если ваш компилятор поддерживает это, вы можете использовать параметризованные производные типы:

  type :: PRM(nrx,maxprx)  ! parameterized derived type definition
    integer, len :: nrx
    integer, len :: maxprx
    real         :: k(nrx,maxprx) 
    ! ...
  end type PRM

(Взято и скорректировано из здесь.)

person Alexander Vogt    schedule 12.02.2015
comment
Просто небольшой вопрос: есть ли здесь какое-либо очевидное преимущество использования массива фиксированного размера? Этот массив просто содержит данные, на которые должны ссылаться различные подпрограммы. Так что я не собираюсь перераспределять его когда-либо. - person WYSIWYG; 13.02.2015