Interface definitions for assumed size arrays

This looks related to the rule recently discussed in this thread: Binding multiple C functions under one Fortran interface - #9 by ivanpribec

When you call a procedure through a generic interface, the standard states:

15.4.3.4.5 Restrictions on generic declarations
[…]

A dummy argument is type, kind, and rank compatible, or TKR compatible, with another dummy argument if the first is type compatible with the second, the kind type parameters of the first have the same values as the corresponding kind type parameters of the second, and both have the same rank or either is assumed-rank.

In other words, when you call a procedure via the generic name, the rank must match too, otherwise the generic resolution fails.

To pass a 2-d array via the generic name, you will need to use rank remapping:

  integer, dimension(3,3), target :: a33
  
  a33 = 3

  block
     integer, pointer :: a1d(:)
     a1d(1:9) => a33
     call x(a1d)
  end block

Edit #1: a second idea (I didn’t test this) would be to introduce a rank-2 wrapper

interface x
   subroutine x(y)
     integer, dimension(*) :: y(*)
   end subroutine
   procedure :: x2d
end interface

! ...

contains

   subroutine x2d(y)
     integer, contiguous :: y(:,:)

     interface
       subroutine x(y)
         integer, dimension(*) :: y
      end subroutine x
     end interface

     call x(y(1))
   end subroutine
end subroutine

Edit #2: a rank-generic procedure is also an option, especially if you are wrapping a C function. The Fortran interface would use an assumed-rank argument:

interface
   subroutine x(y) bind(c,name="x_rank_generic")
     integer, contiguous :: y(..)
   end subroutine
end interface

and on the C side, you would have:

#include <ISO_Fortran_binding.h>

extern void x(int *y); // The actual C procedure

void x_rank_generic(CFI_cdesc_t *y) {
   x((int *) y->base_addr);
}
2 Likes