Reported by James van Buskirk at https://groups.google.com/forum/?fromgroups#!topic/comp.lang.fortran/hb2_DNa5ylY Considering the (supposedly valid) code: module intkinds implicit none private integer, parameter :: Kmax = 10 integer, parameter :: K1 = selected_int_kind(1) integer, parameter :: tK2 = selected_int_kind(range(0_K1)+1) integer, parameter :: cK2 = (sign(1,tK2)+1)/2 integer, parameter :: K2 = cK2*tK2+(1-cK2)*K1 integer, parameter :: tK3 = selected_int_kind(range(0_K2)+1) integer, parameter :: cK3 = (sign(1,tK3)+1)/2 integer, parameter :: K3 = cK3*tK3+(1-cK3)*K2 integer, parameter :: tK4 = selected_int_kind(range(0_K3)+1) integer, parameter :: cK4 = (sign(1,tK4)+1)/2 integer, parameter :: K4 = cK4*tK4+(1-cK4)*K3 integer, parameter :: tK5 = selected_int_kind(range(0_K4)+1) integer, parameter :: cK5 = (sign(1,tK5)+1)/2 integer, parameter :: K5 = cK5*tK5+(1-cK5)*K4 integer, parameter :: tK6 = selected_int_kind(range(0_K5)+1) integer, parameter :: cK6 = (sign(1,tK6)+1)/2 integer, parameter :: K6 = cK6*tK6+(1-cK6)*K5 integer, parameter :: tK7 = selected_int_kind(range(0_K6)+1) integer, parameter :: cK7 = (sign(1,tK7)+1)/2 integer, parameter :: K7 = cK7*tK7+(1-cK7)*K6 integer, parameter :: tK8 = selected_int_kind(range(0_K7)+1) integer, parameter :: cK8 = (sign(1,tK8)+1)/2 integer, parameter :: K8 = cK8*tK8+(1-cK8)*K7 integer, parameter :: tK9 = selected_int_kind(range(0_K8)+1) integer, parameter :: cK9 = (sign(1,tK9)+1)/2 integer, parameter :: K9 = cK9*tK9+(1-cK9)*K8 integer, parameter :: tK10 = selected_int_kind(range(0_K9)+1) integer, parameter :: cK10 = (sign(1,tK10)+1)/2 integer, parameter :: K10 = cK10*tK10+(1-cK10)*K9 integer, parameter :: iKsize = 1+cK2+cK3+cK4+cK5+cK6+cK7+cK8+cK9+cK10 integer, parameter :: tKINDS(Kmax) = (/K1,K2,K3,K4,K5,K6,K7,K8,K9,K10/) integer, parameter, public :: iKINDS(iKsize) = tKINDS(1:iKsize) end module intkinds program testme use intkinds implicit none integer iRANGES(size(iKINDS)) integer i iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) write(*,*) 'iKINDS = ',iKINDS write(*,*) 'iRANGES = ', iRANGES end program testme This is rejected by gfortran 4.7 and earlier with: iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) 1 Error: 'kind' argument of 'int' intrinsic at (1) must be a constant 4.8 and trunk report: iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) 1 Error: Invalid kind for INTEGER at (1) Both errors are apparently wrong, since the KIND argument to the intrinsic INT shall be a scalar integer initialization expression, which it seems to be in this case (for further details and standard quotes see the c.l.f. thread).
As reported by Richard Maine in the c.l.f. thread, NAG compiles the code and produces the following output: iKINDS = 1 2 3 4 iRANGES = 2 4 9 18 When commenting out the lines with 'iRANGES', gfortran prints: iKINDS = 1 2 4 8 16
With this patch ... Index: gcc/fortran/check.c =================================================================== --- gcc/fortran/check.c (revision 202812) +++ gcc/fortran/check.c (working copy) @@ -173,8 +173,8 @@ kind_check (gfc_expr *k, int n, bt type) if (gfc_extract_int (k, &kind) != NULL || gfc_validate_kind (type, kind, true) < 0) { - gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type), - &k->where); + gfc_error ("Invalid kind '%i' for %s at %L", kind, + gfc_basic_typename (type), &k->where); return false; } ... the output is: iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) 1 Error: Invalid kind '0' for INTEGER at (1) This is strange, since none of the iKINDS is zero (as comment 1 shows). In any case, this extension of the error message might be helpful in situations like this, where the kind is not directly supplied by a number, but by some initialization expression ...
I get the same error if I replace iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) with do i = 1, size(iKINDS) print *, range(int(0,iKINDS(i))) end do while print *, range(int(0,iKINDS(1))) print *, range(int(0,iKINDS(2))) ... gives the right answer. I think "print *, range(int(0,iKINDS(i)))" is invalid, however I cannot convince myself that iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/) is. If I am right, it seems that iKINDS(i) is not "expanded" as a constant in the constructor. The following code is working as expected module intkinds implicit none private integer, parameter :: Kmax = 10 integer, parameter :: K1 = selected_int_kind(1) integer, parameter :: rK1 = range(int(0,K1)) integer, parameter :: tK2 = selected_int_kind(range(0_K1)+1) integer, parameter :: cK2 = (sign(1,tK2)+1)/2 integer, parameter :: K2 = cK2*tK2+(1-cK2)*K1 integer, parameter :: rK2 = range(int(0,K2)) integer, parameter :: tK3 = selected_int_kind(range(0_K2)+1) integer, parameter :: cK3 = (sign(1,tK3)+1)/2 integer, parameter :: K3 = cK3*tK3+(1-cK3)*K2 integer, parameter :: rK3 = range(int(0,K3)) integer, parameter :: tK4 = selected_int_kind(range(0_K3)+1) integer, parameter :: cK4 = (sign(1,tK4)+1)/2 integer, parameter :: K4 = cK4*tK4+(1-cK4)*K3 integer, parameter :: rK4 = range(int(0,K4)) integer, parameter :: tK5 = selected_int_kind(range(0_K4)+1) integer, parameter :: cK5 = (sign(1,tK5)+1)/2 integer, parameter :: K5 = cK5*tK5+(1-cK5)*K4 integer, parameter :: rK5 = range(int(0,K5)) integer, parameter :: tK6 = selected_int_kind(range(0_K5)+1) integer, parameter :: cK6 = (sign(1,tK6)+1)/2 integer, parameter :: K6 = cK6*tK6+(1-cK6)*K5 integer, parameter :: rK6 = range(int(0,K6)) integer, parameter :: tK7 = selected_int_kind(range(0_K6)+1) integer, parameter :: cK7 = (sign(1,tK7)+1)/2 integer, parameter :: K7 = cK7*tK7+(1-cK7)*K6 integer, parameter :: rK7 = range(int(0,K7)) integer, parameter :: tK8 = selected_int_kind(range(0_K7)+1) integer, parameter :: cK8 = (sign(1,tK8)+1)/2 integer, parameter :: K8 = cK8*tK8+(1-cK8)*K7 integer, parameter :: rK8 = range(int(0,K8)) integer, parameter :: tK9 = selected_int_kind(range(0_K8)+1) integer, parameter :: cK9 = (sign(1,tK9)+1)/2 integer, parameter :: K9 = cK9*tK9+(1-cK9)*K8 integer, parameter :: rK9 = range(int(0,K9)) integer, parameter :: tK10 = selected_int_kind(range(0_K9)+1) integer, parameter :: cK10 = (sign(1,tK10)+1)/2 integer, parameter :: K10 = cK10*tK10+(1-cK10)*K9 integer, parameter :: rK10 = range(int(0,K10)) integer, parameter :: iKsize = 1+cK2+cK3+cK4+cK5+cK6+cK7+cK8+cK9+cK10 integer, parameter :: tKINDS(Kmax) = (/K1,K2,K3,K4,K5,K6,K7,K8,K9,K10/) integer, parameter :: tRANGES(Kmax) = (/rK1,rK2,rK3,rK4,rK5,rK6,rK7,rK8,rK9,rK10/) integer, parameter, public :: iKINDS(iKsize) = tKINDS(1:iKsize) integer, parameter, public :: iRANGES(iKsize) = tRANGES(1:iKsize) end module intkinds program testme use intkinds implicit none integer i write(*,*) 'iKINDS = ',iKINDS write(*,*) 'iRANGES = ', iRANGES end program testme
Reduced testcase, to summarize: integer, parameter :: arr(1) = [ 1 ] integer, parameter :: x(1) = [( range(int(0,arr(i))), i=1,1 )] integer :: i print *, x print *, range(int(0,arr(1))) end Intel wrongly refuses to compile it ("A kind type parameter must be a compile-time constant"), and IBM compiles it but gives a wrong answer (range of -51378971). So it's indeed tricky code. Both prints should output the same number.