Originally posted by: Rafik_Zurob
C interoperability is one of the most popular features of Fortran 2003. Recently, I was part of a discussion about why XL Fortran flags the following as invalid:
use iso_c_binding
type(c_ptr) p
logical(8), target :: logicalarray(20)
p = c_loc(logicalarray) ! XLF will flag an error here
end
According to Fortran 2003 (and Fortran 2008), the argument to the C_LOC function must either be of an interoperable type or must be a nonpolymorphic scalar. The standard tries to be interoprable with the _Bool type in C, which is of size 1. So the only interoperable logical type is logical(C_BOOL), which is the same as logical(1).
We can get rid of the error in the program above, and make it F2003-compliant, by using the C_BOOL kind from ISO_C_BINDING. i.e.
use iso_c_binding
type(c_ptr) p
logical(c_bool), target :: logicalarray(20)
p = c_loc(logicalarray) ! OK
end
But what if you want to pass a logical(8) array to a C program anyway? If you're willing to part with portability, you can do so by specifying the following compiler options: -qintlog -qport=clogicals. The -qintlog option tells the compiler to treat logicals as integers. Since integer(8) is interoperable, the compiler will not flag the call to C_LOC. The -qport=clogicals option changes XL Fortran's representation of .TRUE.
and .FALSE.
to match C's, i.e. 0 is .FALSE.
and everything else is .TRUE.
. You only need -qport=clogicals if logical variables in your program can have values other than 1 or 0.
There is another workaround that does not require -qintlog: Use C_LOC to take the address of the first element of the array. i.e.
use iso_c_binding
type(c_ptr) p
logical(c_bool), target :: logicalarray(20)
p = c_loc(logicalarray(1)) ! OK
end
This workaround still requires -qport=clogicals, however, to get logical values other than 1 and 0 to have the same meaning in Fortran and C.
I prefer the C_BOOL way, however. After all, the C interoperability part of the Fortran standard is intended to provide a portable way of mixing code written in Fortran and C.