WYSIWYG
WYSIWYG

Reputation: 494

Error in Derived type declaration: Variable at (1) in this context must be constant

I have a derived type declared in a module like this:

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

On compilation I get this error:

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

What is the meaning of "must be a constant"; should it be immutable during compilation i.e. like a PARAMETER?

But there is another issue, I cannot declare PARAMETERS within derived types. How to deal with this error? Would moving these objects out of the derived type and making them PARAMETERS, be the only option?

Most importantly I wish to understand why does this happen.

I was compiling using gfortran: gfortran -Wall -c "dmotifs.f90"

Upvotes: 2

Views: 1919

Answers (1)

Alexander Vogt
Alexander Vogt

Reputation: 18118

Yes. Declaring an explicit-shape array in a non-parameterized derived type requires a constant expression. You could either

  • make k allocatable,dimension(:,:) (and (de-)allocation), or
  • make nrx and maxprx global/module constants (or replace them right away).

If your compiler supports it, you can use parameterized derived types:

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

(Taken and adjusted from here.)

Upvotes: 2

Related Questions