I’m creating generic procedure for two subs with c_float and real dummy argument.
program main
use iso_c_binding
implicit none
interface print_number
procedure:: print_number_real, print_number_c_float
end interface
call print_number(1.0)
contains
subroutine print_number_real(a)
real:: a
print*, a
end subroutine
subroutine print_number_c_float(a)
real(c_float):: a
print*, a
end subroutine
end program
– GCC version 14.1.0
The compiler complains that “Error: Ambiguous interfaces in generic interface ‘print_number’ for ‘print_number_real’ at (1) and ‘print_number_c_float’ at (2)”.
Is the fortran compiler not able to tell the difference between type “c_float” and intrinsic “real”?
No, the compiler interprets “real” as “real(kind=kind(1.0))” and it is highly probable that this kind is the same as c_float - kinds are simply integer numbers, nothing magic about them. Both are single precision (unless you happen to use a compile option to change the default kind).
In the general case there’s no guarantee they would be equal, so there would be some value in a generic interface that could handle the different cases. Is there a way to code it so it would work both in an environment where c_float is the same as the default kind, and where it’s different, without changing the code?
I can think of a preprocessing solution, but otherwise I do not think there is one. Although, you could do something along these lines, if you can spare one precision:
subroutine print_number_real(a)
real:: a
print*, a
end subroutine
! Sacrifice double precision in case default real and c_float are the same
subroutine print_number_c_float(a)
integer, parameter :: cf = merge( kind(1.0d0), c_float, kind(1.0) == c_float )
real(cf):: a
print*, a
end subroutine