On 18/04/2022 08:52, Thomas Koenig wrote:
> I have a C functions I want to interface to, which takes a long
> argument. I also want to have a wrapper function in Fortran
> around it, and operator overloading for it which works for as many
> kinds as possible.
...
> I can then chose a module procedure, but it would silently generate
> wrong code if "long" is 32 bits and I am trying to pass a 64-bit
> integer from Fortran.
It's the silent generation of wrong code that afraid me in a
recent discussion about some user defined interfaces:
https://groups.google.com/g/comp.lang.fortran/c/Akmj_d0opWE/m/ozWk72OJAgAJ
...
> Any ideas?
>
Yes :-)
I've just used the c preprocessor below to avoid making the reply
longer. One doesn't have to use fixed form code as in the example below.
Also, my solution (hackery) uses conditional compilation in module M,
which (I guess) isn't a necessity as well.
Finally, it doesn't seem to be a simple & straightforward solution.
------------------------------------------------------------
macbook:ops suser$ rm -rf *.mod *.smod *.o p.exe
macbook:ops suser$ gfc -c -fopenmp m.f90 -o m.o
macbook:ops suser$ gfc -c sm.F -DN=16 -DS16 -o sm16.o
macbook:ops suser$ gfc -c sm.F -DN=32 -DS32 -o sm32.o
macbook:ops suser$ gfc -c sm.F -DN=64 -DS64 -o sm64.o
macbook:ops suser$ gfc -c sm.F -DN=128 -DS128 -o sm128.o
macbook:ops suser$ gfc -c p.f90 -o p.o
macbook:ops suser$ gfc m.o sm16.o sm32.o sm64.o sm128.o p.o -o p.exe
macbook:ops suser$ ./p.exe
macbook:ops suser$
macbook:ops suser$ rm -rf *.mod *.smod *.o p.exe
macbook:ops suser$ gfc -c -m32 m.f90 -o m.o
macbook:ops suser$ gfc -c -m32 sm.F -DN=16 -DS16 -o sm16.o
macbook:ops suser$ gfc -c -m32 sm.F -DN=32 -DS32 -o sm32.o
macbook:ops suser$ gfc -c -m32 sm.F -DN=64 -DS64 -o sm64.o
macbook:ops suser$ gfc -c -m32 p.f90 -o p.o
macbook:ops suser$ gfc -m32 m.o sm16.o sm32.o sm64.o p.o -o p.exe
ld: warning: The i386 architecture is deprecated for macOS (remove from
the Xcode build setting: ARCHS)
macbook:ops suser$ ./p.exe
macbook:ops suser$ cat m.f90
module m
use, intrinsic :: iso_c_binding
type :: something
real :: x, y
end type something
interface operator(+)
module procedure int16_add, int32_add, int64_add
!$ module procedure int128_add
end interface operator(+)
interface
module function int16_add (a, b) result (c)
type(something), intent(in) :: a
integer(c_int16_t), intent(in) :: b
type(something) :: c
end function int16_add
module function int32_add (a, b) result (c)
type(something), intent(in) :: a
integer(c_int32_t), intent(in) :: b
type(something) :: c
end function int32_add
module function int64_add (a,b) result(c)
type(something), intent(in) :: a
integer(c_int64_t), intent(in) :: b
type(something) :: c
end function int64_add
!$ module function int128_add (a, b) result (c)
!$ type(something), intent(in) :: a
!$ integer(c_int128_t), intent(in) :: b
!$ type(something) :: c
!$ end function int128_add
end interface
end module m
macbook:ops suser$
macbook:ops suser$ cat sm.F
submodule (m) sm N
use, intrinsic :: iso_c_binding
contains
module procedure int N _add
!type(something), intent(in) :: a
!integer(c_int S _t), intent(in) :: b
!type(something) :: c
integer(c_long) bb
bb=b !then check if ( bb /= b )
!call some_c_function (a, bb, c)
end procedure int N _add
end submodule sm N
macbook:ops suser$ cat p.f90
program test
use iso_fortran_env
use, intrinsic :: iso_c_binding
use m
implicit none
integer(c_int16_t) :: c_int16=16;
integer(c_int32_t) :: c_int32=32;
integer(c_int64_t) :: c_int64=64;
integer(c_long) :: a_long =64;
type (something) st;
st = st + 1;
st = st + c_int16;
st = st + c_int32;
st = st + c_int64;
st = st + a_long;
end