PGF90-S-0087-Non-constant expression where constant expression required 
Author Message
 PGF90-S-0087-Non-constant expression where constant expression required

I believe that the following test program and compilation shows an
incorrect limitation in pgf90 version 5.1-2.  Is it overcome in a
later release?

Quote:
> cat t.f90

program t
save
integer :: x(0:0) = (/0/)
integer :: y(0:size(x)-1) = x
end

Quote:
> pgf90 -V t.f90

pgf90 5.1-2
Copyright 1989-2000, The Portland Group, Inc.  All Rights Reserved.
Copyright 2000-2003, STMicroelectronics, Inc.  All Rights Reserved.
PGF90/any Linux/x86 5.1-2
Copyright 1989-2000, The Portland Group, Inc.  All Rights Reserved.
Copyright 2000-2003, STMicroelectronics, Inc.  All Rights Reserved.
PGF90-S-0087-Non-constant expression where constant expression required
(t.f90: 4)
0 inform,   0 warnings,   1 severes, 0 fatal for t

Bas Braams



Fri, 06 Jul 2007 01:27:19 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required

Quote:

>I believe that the following test program and compilation shows an
>incorrect limitation in pgf90 version 5.1-2.  Is it overcome in a
>later release?

>> cat t.f90
>program t
>save
>integer :: x(0:0) = (/0/)
>integer :: y(0:size(x)-1) = x
>end

>> pgf90 -V t.f90
>pgf90 5.1-2
...
>PGF90-S-0087-Non-constant expression where constant expression required
>(t.f90: 4)
>0 inform,   0 warnings,   1 severes, 0 fatal for t

That error message is correct. It's complaining about the  = x
on line 4 of the program, because that line is declaring and
initializing a variable, and what follows the = in that context has
to be a constant. If the previous line had said
   integer,parameter :: x(0:0) = (/0/)
then x would have been a constant and all would have been well - but of
course x would then have been unalterable. If you really want x to be
variable, but given the initial value (/0/), you could change your
declarations to something like

  integer,parameter :: xconst(0:0) = (/0/)
  integer :: x(0:0) = xconst, y(0:size(x)-1) = xconst

Note that although x is not a constant there, size(x) is. Of course
size(xconst) would be too. The general idea is that anything in a
declaration must be evaluatable at compile time. The f95 standard does
not say so because it does not specify how a processor should do its
job, and it says that in section 1.4.

John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington, New Zealand



Fri, 06 Jul 2007 04:36:04 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required

Quote:
> PGF90-S-0087-Non-constant expression where constant expression required
> (t.f90: 4)
> 0 inform,   0 warnings,   1 severes, 0 fatal for t

Yes, this error message is incorrect.  Constant expressions were
effectively eliminated from the language with Corrigendum 1 to f95.
Even before that, an initializer, in this case x, was required to
be an initialization expression.  Note that size(x)-1 is an
initialization expression so that it's OK to use it as a bound of
a saved variable, in this case y, even after Corrigendum 1.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Fri, 06 Jul 2007 05:00:35 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required

Quote:



>>PGF90-S-0087-Non-constant expression where constant expression required
>>(t.f90: 4)
>>0 inform,   0 warnings,   1 severes, 0 fatal for t

> Yes, this error message is incorrect.  Constant expressions were
> effectively eliminated from the language with Corrigendum 1 to f95.

I'm confused. ("Yes, we have no bananas" 8^). Are you saying that
it is incorrect to give an error for this, or that the error
message does not use the correct terminology? I guess the latter,
because you say below that x can't be a variable.

Quote:
> Even before that, an initializer, in this case x, was required to
> be an initialization expression.  Note that size(x)-1 is an
> initialization expression so that it's OK to use it as a bound of
> a saved variable, in this case y, even after Corrigendum 1.

--
Walt Brainerd         +1-877-355-6640 (voice & fax)
The fortran Company   +1-520-760-1397 (outside USA)

Tucson, AZ 85750 USA  http://www.fortran.com


Fri, 06 Jul 2007 06:33:11 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required

Quote:
> I'm confused. ("Yes, we have no bananas" 8^). Are you saying that
> it is incorrect to give an error for this, or that the error
> message does not use the correct terminology? I guess the latter,
> because you say below that x can't be a variable.

Ah, am I talking backwards again?  Time for another example, I
guess.  We know that initialization expressions are a subset of
constant expressions are a subset of restricted expressions.  So
if the compiler really wanted to be a tease, it could give us a
message like:

Error: Variable 'x' cannot appear in restricted expression at (1)

So as good newbie f95 programmers we dutifully look up what this
means and conclude that the compiler is asking for a restricted
expression.  Accordingly, we code up the following:

! File: test2.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   integer :: y(0:ubound(x,1)) = f(2)

   write(*,*) y
end program test

pure recursive function f(x) result(r)
   implicit none
   integer, intent(in) :: x
   integer r

   if(x <= 1) then
      r = 1
   else
      r = x*f(x-1)
   end if
end function f

And are awarded with the error message:

  2018-S: "test2.f90", line 7: When IMPLICIT NONE is specified, f must be
decla
red in a type declaration statement.

OK, so we know how to fix this:

! File: test3.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   integer, external :: f
   integer :: y(0:ubound(x,1)) = f(2)

   write(*,*) y
end program test

pure recursive function f(x) result(r)
   implicit none
   integer, intent(in) :: x
   integer r

   if(x <= 1) then
      r = 1
   else
      r = x*f(x-1)
   end if
end function f

But then we are greeted by the message:

test3.F90(8) : Error: An explicit interface is required for a specification
fu
nction.   [F_LEN]

Undaunted and looking at some more documentation, we attempt:

! File: test4.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   integer :: y(0:ubound(x,1)) = f(2)

   write(*,*) y
   contains
      pure recursive function f(x) result(r)
         implicit none
         integer, intent(in) :: x
         integer r

         if(x <= 1) then
            r = 1
         else
            r = x*f(x-1)
         end if
      end function f
end program test

And now we get:

  1717-S: "test4.f90", line 7, column 34: f already used as an internal fun
ction name.

Kind of difficult to decipher, I know, but from this we conclude that
the problem is that specification functions can't be internal, so we
write:

! File: test5.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   interface
      pure recursive function f(x) result(r)
         implicit none
         integer, intent(in) :: x
         integer r
      end function f
   end interface
   integer :: y(0:ubound(x,1)) = f(2)

   write(*,*) y
end program test

pure recursive function f(x) result(r)
   implicit none
   integer, intent(in) :: x
   integer r

   if(x <= 1) then
      r = 1
   else
      r = x*f(x-1)
   end if
end function f

And we are rewarded by:

Error: Specification function 'f' at (1) cannot be RECURSIVE

Well, we have learned something more, so we can try:

! File: test6.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   interface
      pure function f(x)
         implicit none
         integer, intent(in) :: x
         integer f
      end function f
   end interface
   integer :: y(0:ubound(x,1)) = f(2)

   write(*,*) y
end program test

pure function f(x)
   implicit none
   integer, intent(in) :: x
   integer f
   integer i

   f = 1
   do i = 1, x
      f = f*i
   end do
end function f

And at this point we might expect to encounter the error message:

test6.F90(14) : Error: This array or function or substring is invalid in
consta
nt expressions.   [F]

So after all that, we have found that constant expressions are
required: specification expressions aren't good enough!

! File: test7.f90
! Public domain 2005 James Van Buskirk

program test
   implicit none
   integer, save :: x(0:0) = 0
   integer i
   integer, parameter :: const(5) = (/(i,i=1,size(const))/)
   integer :: y(0:ubound(x,1)) = sum(const)

   write(*,*) y
end program test

So we get:

test7.f90: In function `MAIN_':
test7.f90:4: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.

or:

  0560-S: "test7.f90", line 9: Function not intrinsic function, or intrinsic
fun
ction sum cannot be specified in an initialization expression.

or even:

test7.F90(9) : Error: This intrinsic function is invalid in constant
expressions
.   [SUM]

This is really getting interesting: out of 3 compilers, one gets an
ICE, another prints a correct error message, and the third prints
out an invalid error message!  We know we are starting to write good
f95 when we are getting these kinds of results!

In one more attempt I think, given the second compiler's outout,
we could write a valid initialization expression, but do you see
what I mean about unsatisfactory error messages?  I didn't make
up the above error messages, I just created code that would
generate the kind of error message I was looking for and quoted,
with minor alterations, actual compiler output.  Most of these
compilers started whining about initialization expressions
pretty early on in this sequence.  The error messages for test7.f90
were quoted verbatim, though.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Fri, 06 Jul 2007 09:49:22 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required
In reducing my code to a five-line example I blundered.  I should have
declared x as a constant (parameter), not as a saved and initialized
variable.  Here is my revised problem report, now using a four-line
code for illustration.

Quote:
> cat t.f90

program t
integer, parameter :: x(0:0) = (/0/)
integer :: y(0:size(x)-1) = x
end

Quote:
> pgf90 -V t.f90

pgf90 3.2-4
Copyright 1989-2001, The Portland Group, Inc. All Rights Reserved.
PGF90/any Linux/x86 3.2-4a
Copyright 1989-2001, The Portland Group, Incorporated.  All Rights
Reserved.
PGF90-S-0087-Non-constant expression where constant expression required
(t.f90: 3)
0 inform,   0 warnings,   1 severes, 0 fatal for t
PGF90/any Linux/x86 3.2-4a: compilation completed with severe errors

This is the example that I should have posted originally.  Is it now
clear that the PGF compiler error message is wrong?  It seems that
size(x) is viewed as a non-constant expression.

Has the problem been fixed in a more recent release of the PGI
compiler?

Bas

Quote:



> >I believe that the following test program and compilation shows an
> >incorrect limitation in pgf90 version 5.1-2.  Is it overcome in a
> >later release?

> >> cat t.f90
> >program t
> >save
> >integer :: x(0:0) = (/0/)
> >integer :: y(0:size(x)-1) = x
> >end

> >> pgf90 -V t.f90
> >pgf90 5.1-2
> ...
> >PGF90-S-0087-Non-constant expression where constant expression
required
> >(t.f90: 4)
> >0 inform,   0 warnings,   1 severes, 0 fatal for t

> That error message is correct. It's complaining about the  = x
> on line 4 of the program, because that line is declaring and
> initializing a variable, and what follows the = in that context has
> to be a constant. If the previous line had said
>    integer,parameter :: x(0:0) = (/0/)
> then x would have been a constant and all would have been well - but
of
> course x would then have been unalterable. If you really want x to be
> variable, but given the initial value (/0/), you could change your
> declarations to something like

>   integer,parameter :: xconst(0:0) = (/0/)
>   integer :: x(0:0) = xconst, y(0:size(x)-1) = xconst

> Note that although x is not a constant there, size(x) is. Of course
> size(xconst) would be too. The general idea is that anything in a
> declaration must be evaluatable at compile time. The f95 standard
does
> not say so because it does not specify how a processor should do its
> job, and it says that in section 1.4.

> John Harper, School of Mathematics, Statistics and Computer Science,
> Victoria University, PO Box 600, Wellington, New Zealand


5045


Wed, 11 Jul 2007 10:49:21 GMT  
 PGF90-S-0087-Non-constant expression where constant expression required

Quote:
> This is the example that I should have posted originally.  Is it now
> clear that the PGF compiler error message is wrong?  It seems that
> size(x) is viewed as a non-constant expression.

[sigh]
For any compiler that purports to implement Corrigendum 1 of f95
to say that a constant expression is required is a bug.  And after
all the time I spent creating examples to demonstrate why this
was undesirable...

--

write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Wed, 11 Jul 2007 11:36:11 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. PGF90-S-0087-Non-constant expression where constant expression required

2. Non-constant expression where constant expression required.

3. Lint on a non-constant expression - harmful?

4. optimizing evaluation of constant expressions

5. constant expressions, parameters, `define

6. constant expressions, parameters, `define

7. '87 LRM - constant expression on port

8. Salford compiler: Assigning a value to a constant expression is invalid

9. constants (literal, parameter, expression) in F77

10. complex constants and expression syntax extension a la Mathematica

11. constant expressions & compilers

12. Constant expressions and mathematical functions

 

 
Powered by phpBB® Forum Software