(j3.2006) (SC22WG5.3708) Comment on N1761

Reinhold Bader Reinhold.Bader at lrz.de
Wed Dec 3 08:21:35 EST 2008


Hello,

Aleksandar Donev schrieb:
> Hi,
> 
>> Note especially that MPI
>> calls on scalar buffers can not be done in a backward compatible manner at
>> all.
> I am aware of this but it has nothing to do with MPI. It exists with all of C 
> Interop, and I have complained about it before, and J3/WG5 has explicitly 
> decided to keep it as it is. That is, a C routine for which one makes a 
> BIND(C) interface can either operate on scalars or on arrays, not on both. 
> 
> But, you are convincing me that maybe we should work on fixing this for the 
> TR. We specifically wanted to "fix" it for assumed-rank dummies, that is, we 
> wanted to allow the actual to be either a scalar or an array. Let's discuss 
> and think about it, perhaps off-line on an Interop e-mail list?

before taking this offline, I'd like to understand something about BIND(C)
which other people might know ...

Take the following example program:

module mod_label_interf
  use, intrinsic :: iso_c_binding
  implicit none
  interface foo
    subroutine foo_1(x, n, i) bind(c, name='Foo')
      import :: c_float, c_int
      real(c_float) :: x
      integer(c_int), value :: n, i
    end subroutine
    subroutine foo_2(x, n, i) bind(c, name='Foo')
      import :: c_float, c_int
      real(c_float) :: x(*)
      integer(c_int), value :: n, i
    end subroutine
  end interface
end module
program label_interf
  use mod_label_interf
  implicit none
  integer(c_int) :: i
  real(c_float) :: xx, xxx(3)
  i = 2
  call foo(xx, 1, i)
  call foo(xxx, 3, i)
  write(*, *) xx
  write(*, *) xxx
end program

together with the C implementation

#include <math.h>

void Foo(float *x, int n, int i) {
  int j;
  for (j=0; j<n; j++) {
    *(x+j)  = (float) (i + j) + 0.1;
  }
}

This code is accepted by various processors and executes in accordance with my
personal expectations (for what that is worth :-)).
It is not accepted by NAG's compiler, and also not by IBM xlf. NAG's error message is

Error: label_interf.f90: Duplicate binding label 'Foo' for external procedure FOO_2 and external procedure FOO_1

which references the rules given in clause 16.1. The point I do not understand is that the
interfaces define an external procedure. This seems to contradict the separation between
the definition of a procedure and its interface. More specifically, 2.2.3.1 says that

"an external procedure is a procedure that is defined by an external subprogram or by means other
than Fortran. An external procedure may be invoked by the main program or by any procedure of a
program."

and 12.3 says that

"The interface of a procedure determines the forms of reference through which it may be invoked."

My interpretation is that  in the above interface block using BIND(C), foo_1 is not an external procedure,
but only an alias for the external procedure 'Foo', i.e. foo_1 (and, via the generic interface, foo) is only the
form of reference to 'Foo' as cited above. Through the identical binding label, foo_1 and foo_2 refer to the
same global entity.
In particular, it then should be possible to reference a C pointer argument with a scalar as well
as an array.

If this is wrong, can anyone point out to me what clause in the standard contradicts this?


Regards
Reinhold


More information about the J3 mailing list