[J3] BIND(C) Procedure with Non-interoperable Dummy Argument
malcolm at nag-j.co.jp
malcolm at nag-j.co.jp
Sat Mar 7 06:44:14 UTC 2026
Hi Brad,
This is where you use C_F_POINTER to get the noninteroperable thingo. Normally you'd just use C_LOC and TYPE(C_PTR), but you can also use assumed-rank to pass and receive it. The following works.
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(*), intent(in) :: x(..) ! type(*) cause we're just going to pass it through, (..) to make it a c_desc
end subroutine
end interface
contains
subroutine f_proc(x) bind(c)
type(*), target, intent(in) :: x(..) ! receive with type(*) (..).
type(t), pointer :: xx
call c_f_pointer(c_loc(x),xx)
print *, xx%i
end subroutine
end module
program main
use m
type(t), target :: x
x%i = 42
call c_proc(x)
end program
--
..................Malcolm Cohen, NAG Oxford/Tokyo.
-----Original Message-----
From: J3 <j3-bounces at mailman.j3-fortran.org> On Behalf Of Brad Richardson via J3
Sent: Saturday, March 7, 2026 12:09 AM
To: j3 at mailman.j3-fortran.org
Cc: Brad Richardson <everythingfunctional at protonmail.com>
Subject: [J3] BIND(C) Procedure with Non-interoperable Dummy Argument
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