C/C++ and Fortran

 View Only

C Interoperability: Logical types and C_LOC

By Archive User posted Wed September 21, 2011 11:59 AM

  

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.


0 comments
0 views

Permalink