Re: [MPI3 Fortran] Fwd: [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind
Craig Rasmussen CAS Scientific Programmer [email protected] Ack.... I just did a quick rereading of clause 15, Interoperability with C, and it appears ill defined to me. Consider the following: 1. Suppose a compiler has a default logical size equivalent to a default integer. Since the standard only requires one logical kind, this compiler may not have a type that is interoperable with a _Bool C type. In this instance C_BOOL would be a negative value. 2. If a compiler does support LOGICAL(kind=C_BOOL), what values of a C type _Bool map to .TRUE.? What values map to .FALSE.? These mappings may be in clause 15 but I didn't see them at first glance. 3. Suppose a Fortran compiler has the following mapping: _Bool flag = 0; /* flag maps to .FALSE. */ if (flag != 0) ...; /* flag maps to .TRUE. */ This seems to me to be the sane way to map values from C to Fortran. The same mapping can be done for any C integer type to an equivalently sized Fortran LOGICAL. Also see my specific comments below. -craig On Feb 28, 2013, at 7:10 AM, Tobias Burnus wrote:
Let my try to sum up the proposals in this thread:
(a) LOGICAL(C_Bool) This is interoperable with C99 _Bool and defined within the standard. (One can argue how well-defined it is, esp. on the C99 side.)
May not be interoperable as C_Bool may be negative. Is this even well defined on the Fortran side (see above)?
(b) Using INTEGER(C_INT) That matches the C version's "int", but requires to use integers for Boolean purposes and is odd with the the non-MPI_F08 version.
Here at least a programmer can provide something that is well defined and explicitly convert between integer and LOGICAL types.
Both (a) and (b) require special user handling, e.g. instead of ".true." one has to use ".true._c_bool" or (e.g.) "1"/"MPI_TRUE". In addition, they might cause problems with the MPI 3 goal: "In a single application, it must be possible to link together routines which USE mpi_f08, USE mpi, and INCLUDE 'mpif.h'." (page 598, 17.1 Fortran Support)
(c) Using LOGICAL without BIND(C) That surely works, but it makes the work for the MPI implementation much harder. Without BIND(C), there is no defined C interface and the implementation has to be compiler specific. Especially for dimension(..) and for passing characters (scalar, array, allocatable/pointer or neither), different compilers will handle them differently.
This may be what MPI is forced to do. MPI provides a Fortran only binding for any interface with a Fortran LOGICAL dummy argument. We have to provide wrappers anyway so this can be done but makes a mess of the interfaces (some bind(C) some not) and makes it much more complex for MPI tool writers.
(d) LOGICAL(C_INT) This proposal requires a change of Fortran standard; It effectively matches the current MPI 3 spec. For compilers which implement LOGICAL internally as INTEGER, it is probably fine. However, some compilers don't, e.g. GCC's and NAG's.
I just tested gfortran and Intel Fortran and they both provide LOGICAL(kind=kind(1)) although gfortran provides a WARNING unless tricked.
(1) If one has a different kind value as the normal Fortran LOGICALs, it should work; i.e. kind(.true.) != C_BOOL_INT. But that defies the whole purpose and one could simply use version (a) – or (b).
If one demands C_INT == C_BOOL_INT [or the support of LOGICAL(kind=kind(.true.))], I see three possibilities:
(2) One is to only allow certain values like 0 or 1. This has two down sides: (a) it either forces the user to use the compiler-specific true/false values or the compiler to use some specified values (0 and 1 instead of 0 and -1), including for existing, non-BIND(C) code! (b) It probably will break sooner or later with user code, which uses different values on the C side.
What does Fortran do now for C values?
(3) Or one forces the compiler to accept also other values than .true./.false. As with the previous item, it will affect also all non-Bind(C) logicals. And C_Bool should presumably excluded as one otherwise might get in trouble with the C compiler.
It seems it has to anyway to be compatible with C. I don't have the C99 standard but it appears that there isn't a constant for "true" and "false" without including stdbool.h. Thus a Fortran compiler will have to anticipate values other than .true./.false.
(4) Last, handling dummy arguments/result variables of BIND(C) procedures differently. That probably would work, but it requires a bunch of the careful addition of additional constraints. For instance, to prohibit the TARGET/POINTER attribute for those.
To me this is the only sane response given that C evaluates 0 to false and everything else to true. Nick you want to weigh in on the C standard.
* * *
For me: (a), (c) and (d)(4) are acceptable solutions; I don't like (b) and (d)(1), and I strongly oppose (d)(2) and (d)(3).
Tobias
participants (1)
-
Craig Rasmussen