Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

possible compiler initialization expression bug

Andrew_J_5
Beginner
695 Views

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
Andrew_J_5
Beginner
695 Views

fix typos

0 Kudos
Martyn_C_Intel
Employee
695 Views

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
JVanB
Valued Contributor II
695 Views

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
JVanB
Valued Contributor II
695 Views

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
Martyn_C_Intel
Employee
695 Views

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

0 Kudos
Steve_Lionel
Honored Contributor III
695 Views

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.

0 Kudos
Martyn_C_Intel
Employee
695 Views

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
Reply