[J3] BIND(C) Procedure with Non-interoperable Dummy Argument

Brad Richardson everythingfunctional at protonmail.com
Fri Mar 6 15:08:59 UTC 2026


Hey all,

At one point, reading through the various aspects of C interoperability
in the standard, I had somehow inferred there was a way to opaquely
pass a Fortran entity of non-interoperable type through C via
CFI_cdesc_t. In fact, I even submitting a bug report to gfortran
arguing this should be allowed.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113338

The gist is that given the following excerpts from the standard, I
argued that the following example program should be valid and work.

> C1563 If proc-language-binding-spec is specified for a procedure,
each of its dummy arguments shall be ... or a variable that ... has the
... or POINTER attribute.

> 18.3.7 Interoperability of procedures and procedure interfaces
> A Fortran procedure is interoperable if and only if it has the BIND
attribute, that is, if its interface is specified with a proc-language-
binding-spec.
> A Fortran procedure interface is interoperable with a C function
prototype if
> ...
> (5) any dummy argument without the VALUE attribute corresponds to a
formal parameter of the prototype that is of a pointer type, and either
> ...
> the dummy argument is ..., or a pointer without the CONTIGUOUS
attribute, and the formal parameter is a pointer to CFI_cdesc_t

Fortran program:

module m
  use iso_c_binding

  implicit none

  type :: t ! deliberately NOT BIND(C)
    integer :: i
  end type

  interface
    subroutine c_proc(x) bind(c)
      import t
      implicit none
      type(t), pointer, intent(in) :: x ! note 'pointer'
    end subroutine
  end interface

contains
  subroutine f_proc(x) bind(c)
    type(t), pointer, intent(in) :: x ! note 'pointer'

    print *, x%i
  end subroutine
end module

program main
  use m

  type(t), target :: x

  x%i = 42
  call c_proc(x)
end program

C program:

#include <ISO_Fortran_binding.h>

extern void f_proc(CFI_cdesc_t* x);

extern void c_proc(CFI_cdesc_t* x)
{
  f_proc(x);
}

However, it was recently pointed out to me that the following
constraint also exists

> C1565 A variable that is a dummy argument of a procedure that has a
proc-language-binding-spec shall be assumed-type or of interoperable
type and kind type parameters.

That unfortunately seems pretty cut and dry.

I will note that LVM flang 22, Intel ifx 2023.1.0 and HPE CCE 20.0 all
correctly compile and run the program above. gfortran 15 does not, but
this is reportedly fixed in the gfortran 16 development version.
However, NAG does refuse the program with:

NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7238
Error: interop-bug2.F90, line 15: Argument X of BIND(C) procedure
C_PROC is of non-interoperable type T
Errors in declarations, no further processing for M
Error: interop-bug2.F90, line 26: USE of module M which has errors
Errors in declarations, no further processing for MAIN
[NAG Fortran Compiler error termination, 2 errors]

My question, was there at some point an intention to allow the above
example to be valid, but that C1565 was somehow overlooked? Either way,
would there be any interest in "fixing" this for the next revision? I
don't necessarily think we need to do an interp even if this was an
oversight. Any other thoughts?

Regards,
Brad Richardson



More information about the J3 mailing list