Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
2 Views

possible compiler initialization expression bug

I am getting an initialization expression error for what I believe to be valid code (ifort version 17.0.1). A minimum working example is as below:

program test

    implicit none
    integer :: i, j
    integer, parameter :: L(4) = (/ -9, -4, 0, 4 /)
    integer, parameter :: U(4) = (/ -5, -1, 3, 9 /)
    integer, parameter :: A(-9:9) = (/ ( (/ (J, I = L(J), U(J)) /), J = 1, 4) /)

end program

This results in the compile error

testcase.f90(7): error #6973: This is not a valid initialization expression.   
    integer, parameter :: A(-9:9) = (/ ( (/ (J, I = L(J), U(J)) /), J = 1, 4) /)
---------------------------------------------^
compilation aborted for testcase.f90 (code 1)

Thanks.

0 Kudos
7 Replies
Highlighted
Beginner
2 Views

fix typos

fix typos

0 Kudos
Highlighted
Employee
2 Views

Hi,

Hi,

     I think the compiler is complaining that L(J) and U(J)  in the array constructor for A are not constant scalar integer expressions. L(1) would be a constant; L(J) is not. This array constructor would be fine in executable code, where the loop limits don't have to be constant.

I'm not a standards expert; perhaps others can comment on the interpretation. I did note that gfortran compiled this construct without error.

0 Kudos
Highlighted
Valued Contributor II
2 Views

In the page about constant

In the page about constant expressions (what initialization expressions are now called), the loop variable of an array-constructor implied do is an constant expression provided its bounds and stride are as well. That's a tough one on vendors because that means different elements of an array constructor can have different KINDs so if the array constructor is itself in an ordinary expression, different array elements in the ac-implied-do can be expressions invoking different specific functions with the same generic name. Write code that does that and see how many compilers survive it.

 

0 Kudos
Highlighted
Valued Contributor II
2 Views

An instance of my previous

An instance of my previous post:

module M
   use ISO_FORTRAN_ENV
   implicit none
   interface F
      module procedure F1,F2,F3,F4
   end interface F
   contains
      pure function F1(X)
         integer(INTEGER_KINDS(1)), intent(in) :: X
         real(REAL32) F1
         F1 = X
      end function F1
      pure function F2(X)
         integer(INTEGER_KINDS(2)), intent(in) :: X
         real(REAL64) F2(abs(X)+1)
         integer I
         F2 = [(I,I=1,size(F2))]
      end function F2
      pure function F3(X)
         integer(INTEGER_KINDS(3)), intent(in) :: X
         complex(REAL32) F3
         F3 = X**2
      end function F3
      pure function F4(X)
         integer(INTEGER_KINDS(4)), intent(in) :: X
         integer(INT32) F4(abs(X)+1,abs(X)+1)
         integer I, J
         F4 = reshape([((I**2+J**2,I=1,size(F4,1)),J=1,size(F4,1))],shape(F4))
      end function F4
end module M

program P
   use M
   implicit none
   integer I
   write(*,*) [(mod(I**2+3,7)-3,I=0,3)]
   write(*,*) F(int(1,INTEGER_KINDS(2)))
   write(*,*) F(int(2,INTEGER_KINDS(4)))
   write(*,*) F(int(3,INTEGER_KINDS(3)))
   write(*,*) F(int(4,INTEGER_KINDS(3)))
   write(*,*) F(int(5,INTEGER_KINDS(4)))
   write(*,*) F(int(6,INTEGER_KINDS(2)))
   write(*,*) F(int(7,INTEGER_KINDS(1)))
   write(*,*) F(int(8,INTEGER_KINDS(2)))
   write(*,*) F(int(9,INTEGER_KINDS(4)))
   write(*,*) F(int(10,INTEGER_KINDS(3)))
   write(*,*) [integer::(F(int(I,INTEGER_KINDS(abs(mod(I**2+3,7)-3)+1))),I=1,10)]
end program P

gfortran refuses to compile this while ifort prints out the wrong answer.

 

0 Kudos
Highlighted
Employee
2 Views

I'll forward the examples to

I'll forward the examples to the compiler developers and let them comment.

0 Kudos
Highlighted
Black Belt
2 Views

I agree with RO that the

I agree with RO that the usage in the array constructor is standard-conforming, though you have to go a couple levels deep in the standard to see this.

The standard now refers to "constant expression" - "initialization expression" is no longer used. Constant expression is defined in F2008 section 7.12., and it includes a numbered list of things a "primary" in such an expression can be, The relevant possibilities are:

(1) a constant or subobject of a constant,
(2) an array constructor where each element and each scalar-int-expr of each ac-implied-do-control is a constant expression,
(10) a data-i-do-variable within a data-implied-do,
(11) an ac-do-variable within an array constructor where each scalar-int-expr of the corresponding ac-implied-do-control is a constant expression,

In Andrew's post, we have:

(/ ( (/ (J, I = L(J), U(J)) /), J = 1, 4) /)

J meets item 11, L(J) and U(J) meet item 1, therefore the whole thing is a constant expression. Yes, this requires some gymnastics on the part of the compiler, but I know it already knows how to do much of this. The same issues appear in DATA initialization, by the way.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Employee
2 Views

Thanks, Steve. As you no

Thanks, Steve. As you no doubt realize, this would have been forwarded to you were you still here, in the unlikely event that you hadn't picked it up first.

The front end developers haven't commented yet. I have attached your comments to the internal ticket, dpd200418552..

0 Kudos