[MPI3 Fortran] Fwd: [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind

Craig Rasmussen rasmus at cas.uoregon.edu
Thu Feb 28 12:29:52 CST 2013


Craig Rasmussen
CAS Scientific Programmer
rasmus at cas.uoregon.edu


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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mpi-forum.org/pipermail/mpiwg-fortran/attachments/20130228/ac3bf65c/attachment-0001.html>


More information about the mpiwg-fortran mailing list