0

I am having a problem with using optional arguments. I have two routines num_to_str and qry that take a format fm as an optional argument. When I call qry ("lc"), even though fm is not present, the routine num_to_str thinks fm is present.

Call qry ("lc")

Subroutine qry (lb, fm)
  Character (Len=*), Intent (In), Optional :: lb, fm
  Real :: n 
  Character (Len=65) :: s 

  n = 90.0
  Call num_to_str (n, s, fm)
End Subroutine

Subroutine num_to_str (nb, s, fm)
  Real, Intent (In) :: nb
  Character (Len=*), Intent (In) :: s
  Character (Len=*), Intent (In), Optional :: fm

  fmt = "*"
  if (Present (fm)) fmt = Trim (fm)
End Subroutine  
Zeus
  • 1,485
  • 1
  • 17
  • 33
  • Are explicit interfaces accessible for both subroutines in the scopes in which they are referenced? – IanH Mar 30 '15 at 02:09
  • `num_to_str` is in module `core` whereas `qry` is in module `lattice`. `Present (fm)` in `qry` is returning `T`, however when I try to print `fm` I am getting invalid memory reference. – Zeus Mar 30 '15 at 02:22
  • What compiler/compile options? For the example code shown (note no declaration is present for `fmt`) `present(fm)` should not be true. – IanH Mar 30 '15 at 04:30
  • gfortran -ffree-form -g -J./build/lib. I agree with you, `present (fm)` should be false. – Zeus Mar 30 '15 at 05:40
  • Which compiler version? Try to make a self-contained compilable example. – Vladimir F Героям слава Mar 30 '15 at 07:29
  • As written, your program does not compile, for the following reasons: a) no `END` statement for the main program b) fmt is undeclared and gets a default type of `REAL` which clashes with the assignment of `"*"` c) an explicit interface for `num_to_str` is required in the subroutine `qry` for passing on the optional argument `fm` to `num_to_str` d) gfortran is clever enough to diagnose that `qry` has an optional argument, and it also has not explicit interface. Please fix these problems by editing your original question. –  Mar 30 '15 at 07:47
  • 1
    I am not sure if the problem is solved, but the problem is not occurring this time. Might be that one of the object files was not updated – Zeus Mar 31 '15 at 12:40

1 Answers1

0

The following works for me with both intel fortran and gfortran,

module stuff
  implicit none

contains 

  Subroutine qry (lb, fm)
    Character (Len=*), Intent (In), Optional :: lb, fm
    Real :: n 
    Character (Len=65) :: s

    n = 90.0
    s = "test"
    Call num_to_str (n, s, fm)
  End Subroutine

  Subroutine num_to_str (nb, s, fm)
    Real, Intent (In) :: nb
    Character (Len=*), Intent (In) :: s
    Character (Len=*), Intent (In), Optional :: fm
    Character (Len=65)  :: fmt

    fmt = "*"
    if (Present (fm)) then 
        fmt = Trim (fm)
        print*, nb, s, fm
    else
        print*, nb, s
    endif
  End Subroutine  

end module stuff

program test
  use stuff, only : qry

  Call qry("lc")
  Call qry("lc","f12")

end program test

With output

 $ ./a.out 
 90.000000     test                                                             
 90.000000     test               f12

With optional arguments, you should always use modules (or an explicit interface). Check out this answer

Community
  • 1
  • 1
Ed Smith
  • 12,716
  • 2
  • 43
  • 55