Reputation: 28416
I make huge use of non-1
indexed ALLOCATABLE
arrays, whose actual lower (and thus upper) bounds I want to be known for the procedures they're given to as IN
/INOUT
args (so I declare these dummy arguments as deferred-shape arrays to make them be passed along with their bounds; see f_deferred_all
in the example code).
But.
Sometimes these procedures (after the data-declaration part) can deal with actual arguments being subarrays, so when this is needed, I usually end up making a copy of the procedure, changing its argument declaration along with its name (cf. procedure f_assumed
). And it would be nice to put both procedures under the same name by means of an INTERFACE
. But the standard says I cant, since
Interfaces of specific procedures or bindings are distinguished by fixed properties of their arguments, specifically type, kind type parameters, rank, and whether the dummy argument has the POINTER or ALLOCATABLE attribute.
In the following example program, I overcame this "limitation" by using pointer actual and dummy arguments (see f_deferred_ptr
).
POINTER
s so much.In addition, I defined a pntr
function that returns a POINTER
to its sole (non-ALLOCATABLE
array or section of an array) IN
put argument, so that I can use it "in-line" without defining a POINTER
in the main program and I don't have to put the TARGET
attribute on the actual arguments.
pntr
, a temporary array be created? I think yes, but I'm not sure whether defining the POINTER
and associate it in the main program would make a difference in this respect or not.Here the example follows.
module mymod
implicit none
interface f
module procedure f_deferred_all, f_deferred_ptr!, f_assumed
end interface f
contains
integer function f_assumed(x) result(y)
integer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_assumed
integer function f_deferred_ptr(x) result(y)
integer, pointer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_ptr
integer function f_deferred_all(x) result(y)
integer, allocatable, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_all
function pntr(v) result(vp)
integer, dimension(:), target, intent(in) :: v
integer, dimension(:), pointer :: vp
vp => v
end function pntr
end module mymod
program prog
use mymod
implicit none
integer :: i
integer, dimension(-5:5) :: v1
integer, dimension(:), allocatable :: v2
v1 = [(i, i = 1, 11)]
allocate(v2, source = v1)
print *, 'f_assumed(v1)', f_assumed(v1)
print *, 'f(pntr(v1))', f(pntr(v1(:))) ! is a temporary created?
print *, 'f(v2)', f(v2)
end program prog
Upvotes: 2
Views: 566
Reputation: 94
Your example code is non-conforming because the specific names F_DEFERRED_PTR
and F_DEFERRED_ALL
are ambiguous. Technical Corrigendum f08/0001 changes the wording in "12.4.3.4.5 Restrictions on generic declarations", adding "and not the INTENT(IN) attribute", to
Two dummy arguments are distinguishable if
• one is a procedure and the other is a data object,
• they are both data objects or known to be functions, and neither is TKR compatible with the other,
• one has the ALLOCATABLE attribute and the other has the POINTER attribute and not the INTENT(IN) attribute, or
• one is a function with nonzero rank and the other is not known to be a function.
This is prompted by the fact that the actual argument for a POINTER, INTENT(IN) dummy can be a pointer or a valid target for the dummy pointer in a pointer assignment statement (12.5.2.7 Pointer dummy variables J3/10-007r1). Links to the discussion and resolution of the issue.
Upvotes: 4