Fortran Optional Argument/PRESENT are NOT working in 7.2

Hi,

Optional arguments (or the PRESENT intrinsic function) are apparently not working in versions 7.2-2 and 7.2-3 of the fortran compilers for Linux. I have tested the following program on RHEL 3,4,5 (all 32bit) on both AMD and Intel processors using both the 7.2-2 and 7.2-3 compilers (and some older versions). The PRESENT intrinsic function does not return an appropriate value.

Compiled with pgf90 -o t1 test1.f90

program test1

real :: test_val
test_val = 2.0

call do_ever()

call do_ever(test_val)

end program test1


subroutine do_ever(val)
implicit none
real,optional :: val

if (present(val)) then

write(0,) ‘PRESENT:’
write(0,
) ‘val=’,val

else

write(0,*) ‘NOT PRESENT’

endif

end subroutine do_ever

This generates the following output:

PRESENT:
val= -1.998925
PRESENT:
val= 2.000000

The optional argument is reported as present in both cases - whether or not it is passed. This is causing a number of crash bugs/odd behaviour in various pieces of code since arguments are being loaded that don’t exist. There is at least one user in our group who will have to re-write significant amounts of code to work around this bug.

Checking my other available compiler versions:
7.0-5 demonstrates the same problem
6.1-2 demonstrates the same problem
6.0-5 demonstrates the same problem except that val=0.000 is printed for the invalid case
5.2-2 demonstrates the same problem (output same as 6.0-5)
5.1-3 demonstrates the same problem (output same as 6.0-5)

Has the PRESENT intrinsic function ever worked?

Anyway, if there is some obvious error I am making please let me know.

Cheers,

David

I don’t believe this is a PGI bug. Rather, the use of optional arguments requires the use of an “explicit interface”. Using a module is an easy way to have such an interface. Compare the code below with your original post:

module m1
contains
  subroutine do_ever(val)
    implicit none
    real,optional :: val

    if (present(val)) then
       write(0,*) 'PRESENT:'
       write(0,*) 'val=',val
    else
       write(0,*) 'NOT PRESENT'
    endif

  end subroutine do_ever
end module m1

program test1
  use m1
  real :: test_val
  test_val = 2.0
  
  call do_ever()
  
  call do_ever(test_val)
  
end program test1

Hi All,

Thanks very much for the clarification - it’s my mistake. Apparently, an explicit interface statement is required to make calls to fortran 90 style subroutines unless they are in a module where fortran 90 is the default.

Thanks again!

Cheers,

David