Can an array shape in an interface match the size of multiple fixed arrays?

I have several routines with a parameter p that is an array with an explicit size, like

subroutine foo(p)
integer,dimension(2),intent(in) ::p
end subroutine foo

subroutine bar(p)
integer,dimension(3),intent(in) ::p
end subroutine bar

      

I would call these two functions an indirect call, but couldn't find a way to declare an interface that matches both foo and bar signatures ...

Using the estimated size of the array in an interface, for example, doesn't work:

subroutine indirect(f,p)
integer,dimension(*),intent(in):p
interface
  subroutine f(p)
  integer,dimension(*),intent(in) :: p
  end subroutine f
end interface
call f(p)
end subroutine indirect

      

When I call foo or bar indirectly, the compiler (gfortran 4.9.2) complains about a shape mismatch for the first argument p of f ...

integer,dimension(2) :: pfoo
integer,dimension(3) :: pbar

pfoo = (/ 0,1 /)
pbar = (/ 1,2,3 /)

call foo(pfoo) ! direct call is OK
call bar(pbar)

call indirect(foo,pfoo) ! compiler complains about foo signature
call indirect(bar,pbar) ! same for bar...

      

Compiler error:

Error: Interface mismatch in dummy procedure 'f' at (1): Shape mismatch in dimension 1 of argument 'p'

      

Of course, I could modify the signature of foo and bar to use the assumed array size (*) instead of the fixed array size, but

  • I love that I am losing some information just to make the compiler happy without adding any security

  • foo and bar are not my code and I would not change them ...

I found a workaround, but it consists of writing an assumed sized wrapper for each subroutine foo and bar

call indirect(foo_wrapper,pfoo) ! compiler complains about foo signature
call indirect(bar_wrapper,pbar) ! same for bar...

subroutine foo_wrapper(p)
integer,dimension(*),intent(in) ::p
call foo(p)
end subroutine foo_wrapper

subroutine bar_wrapper(p)
integer,dimension(*),intent(in) ::p
call bar(p)
end subroutine bar_wrapper

      

or, eventually, replacing the entire inferred size with a deferred size in indirect and wrapper to allow for runtime checking also works, but that's not the point ...

Point, since I have a lot of foo / bar like this, there is no way to properly declare the interface (I mean no wrappers or other artifacts).

I could not decipher the standard (I used http://www.j3-fortran.org/doc/year/10/10-007.pdf - I assume it is around 12.5.2.9. The actual arguments related to dummy procedure objects Β§2), so I don't know if this is a gfortran limitation. Right now I don't have any other compiler, but I would like to know if there will be a compiler compiler (intel? - I'm on Windows 7 64 bit).

+1


source to share


1 answer


I'll see if gfortran is right to complain and, no matter what options there are, to get around the complaint. Links to Fortran 2008.

12.5.2.9 is really important.

  • If the interface of a dummy procedure is explicit, its characteristics as a procedure (12.3.1) must be the same as for its effective argument, except that [not applicable]

f

c indirect

is a dummy procedure with an explicit interface (via interface block, 12.4.2.1). Looking at link 12.3.1, we see that

Characteristics of a procedure: .., characteristics of its bogus arguments, ..

foo

, bar

and f

- all procedures with a single dummy argument (all named p

by coincidence). So, if one foo

wants to be an effective argument related to f

, then it foo

p

must match the characteristics f

p

. Each p

is a dummy data object, so 12.3.2.2 becomes relevant:



The characteristics of a dummy data object are its type, its type parameters (if any), its shape, ... If a shape, size, or type parameter is assumed or deferred, it is a characteristic.

We have type and type parameters. However p

, f

B has its own size. p

c foo

does not have such overlapping characteristics. Then it is not allowed to bind foo

with f

in the call indirect

. The same is true for bar

.

This requirement to match the characteristics of dummy data objects with the same shape also naturally leads to another conclusion: foo

and bar

do not have the corresponding characteristics as procedures. For the third procedure, which must match both the shape characteristic, should be ignored.

Using a wrapper routine is possible, but I would also consider if I can modify the various routines to accept the accepted form arguments. This is much better than the suggested size. But as you say, I don't want to change this code either.

For subroutines foo

and bar

like yours, there is another option available. Nothing in these routines requires the caller to have an explicit interface for them (12.4.2.2). So in indirect

you can just drop the interface: the negotiation rules are much more relaxed (other parts 12.5.2.9). However, for other procedures this may not be possible.

All that said ifort seems to happily compile and run the code the way you do it ...

+3


source







All Articles