[MPI3 Fortran] [Mpi-comments] MPI 3.0: Fortran 2008 interface - issue with the LOGICAL kind
Tobias Burnus
burnus at net-b.de
Wed Mar 27 17:44:56 CDT 2013
I restrict myself to replying to Option 4, only, in this email.
Rolf Rabenseifner wrote:
> Option 4:
> (needed for 2c, for all others it is independent)
> - Substituting in mpi_f08
> all CHARACTER(LEN=xxx)
> by CHARACTER(LEN=1),DIMENSION(xxx)
> with xxx = a fixed constant.
>
> As far as I understand, this cannot be done for CHARACTER(LEN=*)
> because otherwise the MPI routine cannot learn about the length
> of the string, see, e.g., argv array in MPI_COMM_SPAWN.
For C interoperability, "character(len=*)" doesn't make sense as with
Bind(C) just a pointer is passed without any length information (and the
string is also not zero-terminated). With Fortran semantics, one either
passes the length as hidden argument or does not pass the pointer to the
data but some descriptor with the length information. In order to make
"len=*" work with Bind(C), the information has to be passed in some way.
However, using
subroutine sub(str, len) Bind(C)
integer :: len
character, dimension(len) :: str
would be one valid replacement - albeit slightly inconvenient. (Without
BIND(C), character(len=len) is also valid but has no advantage to len=*.)
> Pro: As far as I understand, this is needed for BIND(C) for the
> MPI routines that have CHARACTER(LEN=xxx) dummy arguments.
> Con: Non-consistent solution for a bug in TS29113 that should be
> fixed in TS29113.
> The mpi and the mpi_f08 moudlues will be inconsistent to each other. We do not want to change the old mpi module and mpif.h Fortran interface.
Note: For users, both interfaces act exactly in the same way and they
shouldn't be able to detect the difference. (Unless their compiler
doesn't support that part of Fortran 2003. But (nearly) all current
compilers should be able to do so.)
> With current CHARACTER(LEN=xxx), the MPI routine can check at
> runtime whether the provided actual argument is long enough.
> With CHARACTER(LEN=1),DIMENSION(xxx), such a check is impossible.
I fail to see why the diagnostic should be impossible. Compilers are
doing array bounds checks since ages. If the explicit interface is
known, compilers can simply insert a check before the function call. If
the interface is not known, it gets more cumbersome but it is also
possible (e.g. some compiler store in the caller the size of the actual
arguments in a global variable and compare in the callee the values with
the expected sizes).
The only advantage of len=... is that Fortran semantic implies that the
string length of the actual argument is available to the callee, which
makes checking simpler. But of one passes a simple "char *" with
BIND(C), this information is also not available.
In addition, if the the array sizes are known at compile time and an
explicit interface is used (or, as here, both are in the same file), a
compiler can detect the mismatch even at compile time:
Warning: Actual argument contains too few elements for dummy
argument 'x' (3/5)
subroutine foo(x)
character :: x(5)
end
call foo("abc")
end
> Bill and Craig, please correct me if I'm wrong.
> Is this bug fixable in TS29113, or is there a reason,
> why CHARACTER(LEN=xxx) is not interoperable with C?
Well, TS29113 cannot be changed as it is not a bug (solvable via an
interpretation request) and as the TS is published; it would be rather
something for the next Fortran standard.
At least if one does not allow assumed-length, there is no real
fundamental reason to not allow other lengths.
However, one runs into many inconsistencies and has to deal with a lot
of special cases. For instance, while "character(len=1), value" and
"char" are passed in the same way, "character(len=2), value" does not
match any C type. Assuming, one could use "char[]". But then, passing
len=1 by value ("char") and len=2 by reference ("char[]") doesn't look
clean. A "character(len=1)" would be "char *" and "character(len=2)"
then "char**". But what would be "character(len=n)" - what happens if
one changes an "integer :: n = 1" to "integer, paramter :: n=1", would
that change the ABI?
I think there are too many issues like those to make it very unlikely to
be changed in the next standard. In particular, as using
character(len=1), dimension(xxx) :: str
works sufficiently well and it is already implemented in most currently
used compilers. Hence, I believe the standard will only be augmented if
a very strong case can be made that allowing len=1 has large advantages.
(I do not see this happening.)
Tobias
More information about the mpiwg-fortran
mailing list