Consider:
program main
real, allocatable, dimension(:) :: foo
integer n
n=10
call dofoo(foo,n,1)
allocate(foo(n))
call dofoo(foo,n,0)
end program main
subroutine dofoo(foo,n,mode)
real foo(n)
integer i,n,mode
if(mode.eq.1)then
n=6
return
endif
do i=1,n
foo(i)=i
enddo
return
end subroutine dofoo
Is there anything wrong with the above code? (It works with gfortran) I pass in an un-allocated array the first time, but I don't touch it -- Is there anything in the standard that could cause this to behave in a system dependent way?
You've almost answered your own question. Yes, by the standard, it is always illegal to pass an unallocated allocatable arrays as an actual argument if you don't have an interface in scope.
If you have an interface in scope it is only legal if the dummy argument is also allocatable.
And yes I've been bitten by it. My work around has been to allocate to zero size before the call.
The answer by Ian Bush correctly states that the use in the question is not allowed. We can be more precise, though. (References in parentheses to the Fortran 2018 standard.)
There are three cases where an unallocated allocatable actual argument may be used:
There is no exception for "unused" dummy arguments. These restrictions apply whether the allocatable argument is an array or a scalar.
Any other use means that the program is non-conforming (15.5.2.4 p.7, 15.5.2.7 p.2).
In a conforming program, each of these acceptable cases has an explicit interface available. An allocatable or optional dummy argument requires one (15.4.2.2 p.1(3)) and an accessible intrinsic procedure always has an explicit interface available (15.4.2.1 p.1).
These requirements on the program are not ones a compiler is required to be able to analyse. Such a non-conforming program doesn't necessarily mean that you will see problems when compiling and running. In the case of the program of the question, which doesn't attempt to dereference in a bad way, you may well get away with it. However, it's not good to write non-conforming programs and very bad to rely on them "working".
There are some ways where things may go wrong:
value
attribute (again, explicit interface required in this case)That is, your program could behave differently with some compilers/compiler options. Your compiler may refuse to compile the program if it notices that you should have an explicit interface available. The program may abort when entering the subroutine if the runtime checks whether the argument is allocated. The runtime may do something very unexpected if trying to make an anonymous definable copy of the array with the value
attribute when the actual argument isn't allocated.
For the question there's another non-compliance to worry about. The explicit-length dummy argument foo(n)
means that the actual argument must have at least n
elements. An unallocated array doesn't have at least n
elements (for any, even zero, n
). If foo
was intent(out)
a compiler would be within its rights doing something to "undefine" these elements of the actual argument. This may fail.
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