Fortran bind(C) bounds on arrays
Fortran bind(C)
allows Fortran to call C functions and vice versa.
However, Fortran arrays are one-based by default, while C arrays are zero-based.
This can lead to confusion when passing arrays between Fortran and C.
Adding to the confusion is multiple GCC Gfortran versions have
known bugs
that were not fixed as of their final release.
Specifically, the versions of Gfortran known to be working correctly are Gfortran ≤ 8.5 and Gfortran ≥ 12. Known broken GFortran versions are 9.x, 10.x, 11.x.
We show this by example:
program test_bounds
use iso_fortran_env, only : error_unit
implicit none
real, allocatable :: a(:)
integer :: L1,L2, U1,U2
allocate(a(1:2))
L1 = lbound(a,1)
U1 = ubound(a,1)
call c_bounder(a)
L2 = lbound(a,1)
U2 = ubound(a,1)
if (L1 /= L2 .or. U1 /= U2) then
write(error_unit, '(a,2i2,a,2i2)') 'FAIL: bounds changed before/after lower:', L1,L2, " upper: ", U1,U2
error stop
endif
print '(a)', "bounds check OK"
contains
subroutine c_bounder(a) bind(c)
real, intent(inout) :: a(:)
end subroutine c_bounder
end program