- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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.

Link Copied

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

fix typos

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page