- the
bind(C)interface is a vital capability that couples to external programs written in C and C++. - This project does not use
logical(C_BOOL)atbind(C)interfaces due to possibility of bugs with distinct length integers (1 byte) vs. logical (4 bytes) in Fortran. Instead, we useinteger(C_INT)and convert to and from logical in Fortran. - It's perfectly fine to use Fortran
logicalinside this program, and even inside procedures that arebind(C), as long as the interface to C usesinteger(C_INT)and the conversion is handled correctly in Fortran. - to convert from
integer(C_INT)tological, we check if the integer is not equal to zero. This is a common convention in C where zero represents false and any non-zero value represents true. For example:
logical :: flag_fortran
integer(C_INT) :: flag_c
flag_fortran = flag_c /= 0- to convert from
logicaltointeger(C_INT), we can use a simple conditional expression that returns 1 for true and 0 for false. This ensures that the values are correctly interpreted when passed to C functions. For example:
logical :: flag_fortran
integer(C_INT) :: flag_c
flag_c = merge(1, 0, flag_fortran)- examples of these interfaces are in src/libgemini_c.f90
get_config_vars_C()subroutine, where we convert theflagneuBGfrominteger(C_INT)tologicalfor use in Fortran, and then convert it back tointeger(C_INT)before returning to C.
For reference, there were only a couple places that used logical(C_BOOL) in the original code.
- src/libgemini.f90:
type(c_params)has members of typeinteger(C_INT)that represent boolean flags:fortran_nml, fortran_cli, debug, dryrun. - src/libgemini_c.f90:
get_config_vars_C()has a parameterinteger(C_INT) :: flagneuBGused to receive the value from C.