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
Principiante
2.805 Vistas

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 Respuestas
Andrew_J_5
Principiante
2.805 Vistas

fix typos

Martyn_C_Intel
Empleados
2.805 Vistas

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.

JVanB
Colaborador Valioso II
2.805 Vistas

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.

 

JVanB
Colaborador Valioso II
2.805 Vistas

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.

 

Martyn_C_Intel
Empleados
2.805 Vistas

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

Steve_Lionel
Colaborador Distinguido III
2.805 Vistas

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.

Martyn_C_Intel
Empleados
2.805 Vistas

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..

Responder