[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