Is passing NULL as choice argument legal? #533
Labels
chap-environment
MPI Environmental Management Chapter Committee
mpi-5
For inclusion in the MPI 5.0 standard
tl/dr: MPI should specify whether passing an invalid pointer (
NULL
in C) as choice argument is valid if zero elements are to be received/sent.Problem
Passing null-pointer to
memcpy
is undefined behavior in C [1]. The C standard states (N1570, 7.1.4, 1): [emphasize mine]We probably all know that UB is among the worst areas of the C language as it allows compilers to do all kinds of optimizations that users do not expect.
In contrast to
memcpy
, it is not as easy to eliminate a receive or send call because, well, there are two dependent calls on two different processes and leaving out one will cause a deadlock. The MPI standard does not mention whether passing invalid pointers as choice arguments is valid if the message is empty. Section 2.5.5. simply states: [emphasize mine]Consider this example:
Now consider a simplified implemenation of
MPI_Recv
that eventually performs amemcpy
intobuf
:Last, consider that the compiler is actually able to see that implementation, e.g., because everything was compiled with link-time-optimization enabled. In that case, the assert in
recv
will trigger ifbuf == NULL && cnt == 0
because the compiler may assume thatbuf != NULL
after the inlined call tomemcpy
(because UB). For a demonstration, see this example (notice how the conditional before theassert
after thememcpy
is optimized out and thus will abort the program ifbuf == NULL
andcnt == 0
).Looking at the relevant sentence in the standard, such an implementation of
MPI_Recv
might be permissible under a strict interpretation:The
NULL
pointer is not a reference to an actual object (or argument, for that matter) so there is no reason to ever expect it.Note, that the C standard requires pointers to point to valid objects even if zero elements are copied:
(N1570, 7.24.1, 2)
Given that, the call to
memcpy
in the above implementation ofMPI_Recv
is legal under the strict interpretation outlined above.Proposal
Add verbiage to the standard requiring implementations to ignore choice arguments if the pointer can be expected to point to zero elements:
This would cover all relevant function (P2P, collective, RMA) where zero can be passed as the number of elements.
Changes to the Text
See above
Impact on Implementations
Implementations may not use application-provided invalid pointers for anything other than comparison. In other words, implementations have to make sure that a pointer is non-NULL before passing it into
memcpy
(or any similar C standard function to which (N1570, 7.1.4, 1) cited above applies) or otherwise de-referencing. The simplified implementation could then be:The conditional before the call to
memcpy
prevents UB and thus the assert from triggering ifbuf == NULL
.This seems more prudent than requiring applications to pass non-NULL pointers to MPI even if zero elements are to be transferred. I assume that most implementations are already performing that check (or do not use function that trigger such UB), so the impact on implementations should be minimal.
Impact on Users
Clarification that passing invalid pointers to MPI is legal if no elements are actually accessed and the guarantee that this does not create undefined behavior, under no circumstance.
References and Pull Requests
[1] https://en.cppreference.com/w/c/string/byte/memcpy
The text was updated successfully, but these errors were encountered: