-
Notifications
You must be signed in to change notification settings - Fork 914
Description
This is with v5.0.8, but the code looks the same as in main
.
At the moment, ompi_fortran_string_c2f
uses opal_string_copy
to copy a string into the destination and then replaces the null-terminator and all remaining characters of the buffer with spaces as expected by the Fortran standard.
ompi/ompi/mpi/fortran/base/strings.c
Lines 79 to 103 in 5f5cd62
/* | |
* Copy a C string into a Fortran string. Note that when Fortran | |
* copies strings, even if it operates on subsets of the strings, it | |
* is expected to zero out the rest of the string with spaces. Hence, | |
* when calling this function, the "len" parameter should be the | |
* compiler-passed length of the entire string, even if you're copying | |
* over less than the full string. Specifically: | |
* | |
* http://www.ibiblio.org/pub/languages/fortran/ch2-13.html | |
* | |
* "Whole operations 'using' only 'part' of it, e.g. assignment of a | |
* shorter string, or reading a shorter record, automatically pads the | |
* rest of the string with blanks." | |
*/ | |
int ompi_fortran_string_c2f(const char *cstr, char *fstr, int len) | |
{ | |
int i; | |
opal_string_copy(fstr, cstr, len); | |
for (i = strlen(cstr); i < len; ++i) { | |
fstr[i] = ' '; | |
} | |
return OMPI_SUCCESS; | |
} |
However, this fails when the length of the destination is less than or equal to the length of the source string: opal_string_copy
copies up to the length of the destination but then replaces the last character with \0
. Then the loop to replace the rest of the destination with spaces doesn't do anything (because it starts from the length of the source) and you're left with a \0
as the last character in the destination.
I noticed this because it breaks mpifh's and use_mpi's MPI_Info_get
when the destination is exactly the length of the value:
use mpi
character(len=3) :: value = "bar"
integer :: info, ierr
logical :: flag
call MPI_Info_create(info, ierr)
call MPI_Info_set(info, "foo", value, ierr)
call MPI_Info_get(info, "foo", len(value), value, flag, ierr)
call MPI_Info_free(info, ierr)
results in value
containing ba\0
when it should still contain bar
.
As an aside: MPI_Info_get
/ ompi_info_get_f
doesn't actually use the valuelen
argument and instead only uses the compiler-provided length argument. I'm not sure what the behaviour should be when given a smaller length than the actual destination, especially if the value is larger than the provided length. At the moment it will return the whole value (up to (length-1) of the destination) but should it instead be truncating it there and filling the rest of the destination with spaces?