GNU Fortran (GCC) 4.3.0 20070412 (experimental) Linux 2.4.20-20030701 #2 SMP use ped_class type (ped_data) :: dataset integer, dimension(dataset%maxsiz) :: nobs works but use ped_class integer, dimension(dataset%maxsiz) :: nobs type (ped_data) :: dataset doesn't. ped_data is defined in module ped_class and has an integer slot %maxsiz
Could you post a complete example? I have problems to create one with type (ped_data) :: dataset integer, dimension(dataset%maxsiz) :: nobs as parameter is not allowed in a type specification and using a simple type ped_data integer :: maxsiz = 5 end type ped_data does also not work: integer, dimension(dataset%maxsiz) :: nobs 1 Error: Variable 'dataset' cannot appear in the expression at (1) or in words of NAG f95: DATASET is not permitted in a specification expression
(In reply to comment #0) > GNU Fortran (GCC) 4.3.0 20070412 (experimental) > Linux 2.4.20-20030701 #2 SMP > > use ped_class > type (ped_data) :: dataset > integer, dimension(dataset%maxsiz) :: nobs > > works but > > use ped_class > integer, dimension(dataset%maxsiz) :: nobs > type (ped_data) :: dataset > > doesn't. If I understand you correctly, what you're trying to do is invalid. You may only reference previously declared objects in data object declarations. In your second example dataset is referenced before it is declared. Please provide a complete testcase, and if the problem is indeed the order of declarations please tell us where you think I'm wrong.
Subject: Re: Array size declaration depended on order of declaration of variable containing size On Sat, 13 Apr 2007, tobi at gcc dot gnu dot org wrote: > > > ------- Comment #2 from tobi at gcc dot gnu dot org 2007-04-13 15:22 ------- > (In reply to comment #0) >> GNU Fortran (GCC) 4.3.0 20070412 (experimental) >> Linux 2.4.20-20030701 #2 SMP >> >> use ped_class >> type (ped_data) :: dataset >> integer, dimension(dataset%maxsiz) :: nobs >> >> works but >> >> use ped_class >> integer, dimension(dataset%maxsiz) :: nobs >> type (ped_data) :: dataset >> >> doesn't. > > If I understand you correctly, what you're trying to do is invalid. You may > only reference previously declared objects in data object declarations. In > your second example dataset is referenced before it is declared. > > Please provide a complete testcase, and if the problem is indeed the order of > declarations please tell us where you think I'm wrong. > Hi. Please find a cutdown example attached. In this form, it compiles successfully with gfortran, ifort and g95. If line 251 is commented out and line 256 uncommented, only g95 compiles it successfully. Since dataset, nobs and relid are all subroutine arguments, it seems plausible to me that the order of declaration should be irrelevant, even though it require more work by the compiler. I haven't looked at the Fortran Standard (and probably couldn't work out what it was saying anyway ;)) to see if there is a defined behaviour. Cheers, David Duffy.
Created attachment 13364 [details] example
Subject: Re: Array size declaration depended on order of declaration of variable containing size You wrote: > as parameter is not allowed in a type specification and using a simple > type ped_data > integer :: maxsiz = 5 > end type ped_data > does also not work: > integer, dimension(dataset%maxsiz) :: nobs > 1 > Error: Variable 'dataset' cannot appear in the expression at (1) > or in words of NAG f95: > DATASET is not permitted in a specification expression and tobi at gcc dot gnu dot org wrote: > > > ------- Comment #2 from tobi at gcc dot gnu dot org 2007-04-13 15:22 ------- > (In reply to comment #0) >> GNU Fortran (GCC) 4.3.0 20070412 (experimental) >> Linux 2.4.20-20030701 #2 SMP >> >> use ped_class >> type (ped_data) :: dataset >> integer, dimension(dataset%maxsiz) :: nobs >> >> works but >> >> use ped_class >> integer, dimension(dataset%maxsiz) :: nobs >> type (ped_data) :: dataset >> >> doesn't. > > If I understand you correctly, what you're trying to do is invalid. You may > only reference previously declared objects in data object declarations. In > your second example dataset is referenced before it is declared. > > Please provide a complete testcase, and if the problem is indeed the order of > declarations please tell us where you think I'm wrong. > Hi. Please find a cutdown example attached. In this form, it compiles successfully with gfortran, ifort and g95. If line 251 is commented out and line 256 uncommented, only g95 compiles it successfully. Since dataset, nobs and relid are all subroutine arguments, it seems plausible to me that the order of declaration should be irrelevant, even though it require more work by the compiler. I haven't looked at the Fortran Standard (and probably couldn't work out what it was saying anyway ;)) to see if there is a defined behaviour. Cheers, David Duffy. ! ! Output stream ! module outstream integer :: outstr end module outstream ! ! One big pedigree data structure ! Updating size requires copying entire structure ! (hopefully maintaining contiguous storage) ! module idstring_widths integer, parameter :: ped_width = 20 integer, parameter :: id_width = 12 end module idstring_widths module ped_class use idstring_widths type ped_data integer :: nped ! number of pedigrees integer :: nact ! number of active pedigrees integer :: maxsiz ! size of largest pedigree integer :: nobs ! number of records integer :: numloc ! number of columns of locus data ! pedigree level data character (len=ped_width), dimension(:), allocatable :: pedigree integer, dimension(:), allocatable :: num integer, dimension(:), allocatable :: nfound integer, dimension(:), allocatable :: actset ! individual level data integer, dimension(:), allocatable :: iped character (len=id_width), dimension(:), allocatable :: id integer, dimension(:), allocatable :: fa integer, dimension(:), allocatable :: mo integer, dimension(:), allocatable :: sex double precision, dimension(:,:), allocatable :: locus ! useful work arrays -- usually referring to locus being currently analysed logical, dimension(:), allocatable :: untyped end type ped_data contains ! ! allocate pedigree data ! subroutine setup_peds(nped, nobs, numloc, dataset) integer :: nobs, nped, numloc type (ped_data) :: dataset dataset%nped = nped dataset%nact = nped dataset%maxsiz = 0 dataset%nobs = nobs dataset%numloc = numloc allocate(dataset%pedigree(nped)) allocate(dataset%num(0:nped)) allocate(dataset%nfound(nped)) allocate(dataset%actset(nped)) dataset%num(0)=0 allocate(dataset%iped(nobs)) allocate(dataset%id(nobs)) allocate(dataset%fa(nobs)) allocate(dataset%mo(nobs)) allocate(dataset%sex(nobs)) allocate(dataset%locus(nobs, numloc)) allocate(dataset%untyped(nobs)) end subroutine setup_peds ! ! copy pedigree data ! subroutine copy_peds(set1, set2) type (ped_data) :: set1, set2 integer :: i set2%nped = set1%nped set2%nact = set1%nact set2%maxsiz = set1%maxsiz set2%nobs = set1%nobs set2%numloc = set1%numloc do i=0, set1%nped set2%num(i) = set1%num(i) end do do i=1, set1%nped set2%pedigree(i) = set1%pedigree(i) set2%nfound(i) = set1%nfound(i) set2%actset(i) = set1%actset(i) end do do i=1, set1%nobs set2%iped(i) = set1%iped(i) set2%id(i) = set1%id(i) set2%fa(i) = set1%fa(i) set2%mo(i) = set1%mo(i) set2%sex(i) = set1%sex(i) set2%locus(i, 1:set1%numloc) = set1%locus(i, 1:set1%numloc) end do end subroutine copy_peds ! ! deallocate pedigree structure arrays ! subroutine cleanup_peds(dataset) type (ped_data) :: dataset if (allocated(dataset%locus)) then deallocate(dataset%pedigree) deallocate(dataset%num) deallocate(dataset%nfound) deallocate(dataset%actset) deallocate(dataset%iped) deallocate(dataset%id) deallocate(dataset%fa) deallocate(dataset%mo) deallocate(dataset%sex) deallocate(dataset%locus) deallocate(dataset%untyped) end if dataset%nped=0 dataset%nact=0 dataset%maxsiz=0 dataset%nobs=0 dataset%numloc=0 end subroutine cleanup_peds end module ped_class program tester use outstream use ped_class type (ped_data) :: work integer :: MISS=-9999 outstr=6 call setup_peds(1, 4, 1, work) work%maxsiz=4 work%pedigree(1)='Test' work%num(1)=4 work%nfound(1)=2 work%actset(1)=2 work%iped=1 work%id(1)='1' work%id(2)='2' work%id(3)='3' work%id(4)='4' work%fa=MISS work%mo=MISS work%fa(3)=1 work%mo(3)=2 work%fa(4)=1 work%mo(4)=2 work%sex=1 work%locus=1.0d0 call getrelval('sib', 'mea', 'test', 4, 1, MISS, work, 0) call cleanup_peds(work) end program tester ! ! Get values for trait in relatives ! subroutine getrelval(relate, summary, locnam, loctyp, trait, & sumval, dataset, plevel) use outstream use ped_class implicit none character (len=3), intent(in) :: relate, summary character (len=10), intent(in) :: locnam integer, intent(in) :: loctyp integer, intent(in) :: trait, sumval type (ped_data) :: dataset integer, intent(in) :: plevel ! integer, parameter :: MISS=-9999, MAXREC=20 ! trait values in relatives integer, dimension(dataset%maxsiz) :: nobs integer, dimension(dataset%maxsiz, MAXREC) :: relid integer :: currf, currm, i, idx, j, k, nsibs, num, pedoffset, ped, pos, & reltyp, totobs character (len=1) :: ch character (len=6), dimension(13) :: relnam = (/ 'All ', & 'Offspring', 'Son ', 'Daughter ', & 'Parent ', 'Father ', 'Mother ', & 'Sibling ', 'Brother ', 'Sister ', & 'Spouse ', 'Husband ', 'Wife ' /) reltyp=1 if (relate=='sib') then reltyp=8 end if if (plevel >= 0) then write(outstr, '(/3a/a)') 'Pedigree ID Rel Summary (', summary, ')', & '------------ ------------ --- --------------------' end if totobs=0 ! Siblings if (reltyp==8 .or. reltyp==9 .or. reltyp==10) then do ped=1, dataset%nped if (dataset%actset(ped) > 0) then pedoffset=dataset%num(ped-1)+dataset%nfound(ped) num=dataset%num(ped)-dataset%num(ped-1) do k=1, num nobs(k)=-1 end do nobs((dataset%nfound(ped)+1):num)=0 currf=MISS currm=MISS idx=num i=dataset%num(ped) do while (i > pedoffset) currf=dataset%fa(i) currm=dataset%mo(i) nsibs=0 pos=i-1 do while (dataset%fa(pos)==currf .and. dataset%mo(pos)==currm) nsibs=nsibs+1 pos=pos-1 end do do j=pos+1, i if (reltyp==8 .or. (reltyp==9 .and. dataset%sex(j)==1) .or. & (reltyp==10 .and. dataset%sex(j)==2)) then if (dataset%locus(j,trait) /= MISS .and. nobs(idx) < MAXREC) then nobs(idx)=nobs(idx)+1 relid(idx, nobs(idx))=j end if end if end do do j=idx-nsibs, idx-1 nobs(j)=nobs(idx) do k=1, nobs(idx) relid(j,k)=relid(idx,k) end do end do i=pos idx=idx-nsibs-1 end do call prirelval(relnam(reltyp), summary, trait, loctyp, ped, nobs, relid, & sumval, totobs, dataset, plevel) end if end do end if if (plevel <= 0 .and. totobs>=30) then write(outstr, '(a)') '...' end if write(outstr, '(/a,i6,a)') & 'Processed', totobs, ' trait values from relatives.' end subroutine getrelval ! ! Output values for each eligible persion ! subroutine prirelval(relate, summary, trait, loctyp, ped, & nobs, relid, sumval, totobs, dataset, plevel) use outstream use ped_class implicit none integer, parameter :: MAXREC=20 character (len=3), intent(in) :: relate character (len=3), intent(in) :: summary integer, intent(in) :: trait, loctyp integer, intent(in) :: ped ! FROM HERE type (ped_data) :: dataset ! trait values in relatives integer, dimension(dataset%maxsiz) :: nobs integer, dimension(dataset%maxsiz, MAXREC) :: relid ! TO HERE ! type (ped_data) :: dataset integer, intent(in) :: sumval integer, intent(inout) :: totobs integer, intent(in) :: plevel ! integer, parameter :: MISS=-9999 integer :: i, idx, j, n, pedoffset double precision :: res character (len=1) :: ch ! functions ! ! Detailed output ! pedoffset=dataset%num(ped-1) if (summary=='sum' .or. summary=='mea') then idx=0 do i=pedoffset+1, dataset%num(ped) idx=idx+1 res=MISS if (nobs(idx) > 0) then totobs=totobs+1 res=0.0d0 do j=1, nobs(idx) res=res+dataset%locus(relid(idx,j),trait) end do if (loctyp==4) res=res-dfloat(nobs(idx)) if (summary=='mea') res=res/dfloat(nobs(idx)) if (plevel>0 .or. (plevel==0 .and. totobs<30)) then write(outstr, '(a12,1x,a12,1x,a3,1x,f16.4)') & dataset%pedigree(ped), dataset%id(i), relate, res end if else if (nobs(idx) == 0 .and. & (plevel>0 .or. (plevel==0 .and. totobs<30))) then write(outstr, '(a12,1x,a12,1x,a3,12x,a)') & dataset%pedigree(ped), dataset%id(i), relate, 'x' end if if (sumval /= MISS) dataset%locus(i, sumval)=res end do end if end subroutine prirelval ! ! binary trait as character ! subroutine wraff(value, ch, typ) double precision, intent(in) :: value character (len=1), intent(out) :: ch integer, intent(in) :: typ character (len=1), dimension(6), parameter :: let=(/'x','n','y','?','U','A'/) ch=let(1+3*(typ-1)) if (value == 1.0d0) then ch=let(2+3*(typ-1)) else if (value == 2.0d0) then ch=let(3+3*(typ-1)) end if end subroutine wraff
> Created an attachment (id=13364) [edit] This is only standard conform after changing dfloat() to real(..., kind(0d0)) and after changing call getrelval('sib', 'mea', 'test', 4, 1, MISS, work, 0) into call getrelval('sib', 'mea', 'test ', 4, 1, MISS, work, 0) With these changes it is Fortran 2003 standard conform and also compiles with NAG f95 > If line 251 is commented out and line 256 uncommented, only g95 compiles it > successfully. > Since dataset, nobs and relid are all subroutine arguments, it seems > plausible to me that the order of declaration should be irrelevant, even > though it require more work by the compiler. I haven't looked at the Fortran > Standard (and probably couldn't work out what it was saying anyway ;)) to see > if there is a defined behaviour. integer, dimension(dataset%maxsiz) :: nobs integer, dimension(dataset%maxsiz, MAXREC) :: relid type (ped_data) :: dataset I think gfortran rightly rejects the file though the error message should be improved. NAG f95 writes: Error: z.f90, line 253: Implicit type for DATASET detected at %@MAXSIZ Error: z.f90, line 253: DATASET is not of derived type detected at %@MAXSIZ Error: z.f90, line 256: Symbol DATASET has already been implicitly typed detected at ::@DATASET ifort is also better: fortcom: Error: z.f90, line 253: The structure-name is invalid or is missing. integer, dimension(dataset%maxsiz) :: nobs gfortran: Error: Expected another dimension in array declaration at (1) and later: Error: Symbol 'nobs' at (1) has no IMPLICIT type If I'm not mistaken, the relevant part of the standard is: "A variable within a specification expression shall have its type and type parameters, if any, specified by a previous declaration in the same scoping unit, by the implicit typing rules in effect for the scoping unit, or by host or use association. If a variable in a specification expression is typed by the implicit typing rules, its appearance in any subsequent type declaration statement shall confirm the implied type and type parameters."
Subject: Re: improve error message for using specification expr. of later decl. On Wed, 22 May 2007, burnus at gcc dot gnu dot org wrote: > I think gfortran rightly rejects the file though the error message should be > improved. Thanks for spending so much time on this! I might mention that the actual program the example comes from compiles with gfortran and runs beautifully on my data, while the executable compiled with ifort segfaults (I have yet to sort out why). Cheers, David Duffy.
Here is a minimal testcase that reproduces the unclear error message: subroutine prirelval(nobs, dataset) type ped_data integer :: maxsiz end type ped_data integer, dimension(dataset%maxsiz) :: nobs type (ped_data) :: dataset end subroutine prirelval $ gfortran z.f90 z.f90:6.28: integer, dimension(dataset%maxsiz) :: nobs 1 Error: Expected another dimension in array declaration at (1)
*** Bug 35951 has been marked as a duplicate of this bug. ***
The error for the test in comment 8 is now (from 4.8 up to trunk 6.0) pr31560_1.f90:6:29: integer, dimension(dataset%maxsiz) :: nobs 1 Error: Symbol 'dataset' at (1) has no IMPLICIT type Is there any hope to emit an error of the kind "used before it is defined"? or should this PR closed as FIXED?
> The error for the test in comment 8 is now (from 4.8 up to trunk 6.0) > > pr31560_1.f90:6:29: > > integer, dimension(dataset%maxsiz) :: nobs > 1 > Error: Symbol 'dataset' at (1) has no IMPLICIT type > > Is there any hope to emit an error of the kind "used before it is defined"? > or should this PR closed as FIXED? No feed-back, closing as FIXED.