Re: PGF90-S-0087-Non-constant expression where constant expression required

From: James Van Buskirk (not_valid_at_comcast.net)
Date: 01/17/05

  • Next message: beliavsky_at_aol.com: "Redefining a numeric constant in Fortran (Was Re: why are some types immutable?)"
    Date: Sun, 16 Jan 2005 18:49:22 -0700
    
    

    "Walt Brainerd" <walt@fortran.com> wrote in message
    news:41EAEBA7.70805@fortran.com...

    > 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
    

  • Next message: beliavsky_at_aol.com: "Redefining a numeric constant in Fortran (Was Re: why are some types immutable?)"

    Relevant Pages