I am having a problem with the OPTIONAL
statement in functions and subroutines with Fortran 95. Currently I am using Silverfrost's Plato and their FTN95 compiler (in "Release Win32" mode). After trying to implement the OPTIONAL statement in a more complex program I am writing, I created a very simple program to test it. Here is the code:
program TEST
implicit none
integer :: a=1, b=2
call Z(a,b)
call Z(a)
call Z(b)
end program TEST
subroutine Z(x,y)
implicit none
integer :: x
integer, optional :: y
if (present(y)) then
write(*,*) x, y
else
write(*,*) x
endif
end subroutine Z
I expected the following result displayed on the screen:
1 2
1
2
Well, the code compiles, although I get a warning (673) that "SUBROUTINE Z has been called with too few arguments". After executing it, I get on my screen:
1 2
and then an "Access violation" error message. Can somebody understand what is wrong here?
Thanks a lot! Gilberto
Try putting the subroutine in a module, like so:
module testoptional
contains
subroutine Z(x,y)
implicit none
integer :: x
integer, optional :: y
if (present(y)) then
write(*,*) x, y
else
write(*,*) x
endif
end subroutine Z
end module testoptional
program TEST
use testoptional
implicit none
integer :: a=1, b=2
call Z(a,b)
call Z(a)
call Z(b)
end program TEST
Compiling and running then gives the expected result using gfortran and ifort.
The problem is in how the main program knows (or guesses) the interface to Z(x,y)
. In the code you provide, although the main program and the subroutine are in the same file, there's nothing explicitly telling the main program the interface - the calling sequence, including argument counts, types, etc - of Z
. The first call is to Z(a,b)
, so it infers there's a subroutine out there somewhere that takes two parameters; then it tries calling it with one parameter, which fails.
Putting the subroutine in a module, then using the module (you could also use contains
for a contained subroutine, or explicitly/manually providing the main program the interface using an interface
block) then gives the main program the information it needs about the calling sequence - e.g., that there's an optional argument - and things work correctly.
Procedures with optional arguments must have explicit interfaces, so try giving one to Z
. (E.g. just use the subroutine from a short module.)
I don't have this specific compiler on hand, but I've gotten an error when using the Cray compiler for cases like this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With