The MPI standard indeed has provisions for language interoperability - the whole §16.3 of the MPI 2.2 document is dedicated to language interoperability between Fortran and C.
§16.3.10 Interlanguage Communication
The type maching rules for communications in MPI anr not changed: the datatype specification for each item sent should match, in type signature, the datatype specification used to receive this item (unless one of the types is MPI_PACKED). Also, the type of a message item should match the type declaration for the corresponding communication buffer location, unless the type is MPI_BYTE or MPI_PACKED. Interlanguage communication is allowed if it complies with these rules.
Then it goes on to show an example where the same construced datatype is used to send a message from a Fortran code and to receive it in a piece of C code. The type is constructed so as to allow the C code to receive the data into a buffer that belongs to the Fortran code, but what is more relevant to your question is that the C code uses a datatype that was constructed from the Fortran MPI_REAL. Using Fortran datatypes in C functions and vice versa is perfectly legal if it makes sense:
§16.3.6 MPI Opaque Objects - Datatypes
... If a datatype defined in one language is used for a communication call in another language, then the message sent will be identical to the message that would be sent from the first language: the same communication buffer is accessed, and the same representation conversion is performed, if needed. All predefined datatypes can be used in datatype constructors in any language. If a datatype is committed, it can be used for communication in any language.
(predefined MPI datatypes like MPI_REAL and MPI_DOUBLE are committed)
On the contrary, using Fortran datatypes on the one side and C datatypes on the other is allowed but considered not portable:
§16.3.10 Interlanguage Communication
... MPI implementations may weaken these type matching rules, and allow messages to be sent with Fortran types and received with C types, and vice versa, when those types match. I.e., if the Fortran type INTEGER is identical to the C type int, then an MPI implementation may allow data to be sent with datatype MPI_INTEGER and be received with datatype MPI_INT. However, such code is not portable.
(emphasis mine)
Changing REAL(8) to DOUBLE PRECISION does nothing to increase the portablity of your code as the Fortran standard guarantees nothing about the representation of the DOUBLE PRECISION type - it only says that DOUBLE PRECISION is an alternative specifier for one kind of REAL type, namely the double precision kind, which should have greater decimal precision than the default real. Sending REAL(8) with a datatype of MPI_DOUBLE_PRECISION is not portable. Instead a portable program would use the SELECTED_REAL_KIND intrinsic of Fortran together with MPI_Type_create_f90_real to register a matching MPI datatype.
The best option IMHO is to rely on the language interoperability between C and Fortran and stick to the same datatypes on both sides. Since your compiler suite is recent enough, you can use the ISO_C_BINDING mechanism of Fortran to get REAL and INTEGER kinds, compatible with C, and use the C datatypes in the Fortran calls. For example:
USE, INTRINSIC :: ISO_C_BINDING
REAL(C_DOUBLE), DIMENSION(10) :: darray
INTEGER(C_INT) :: ival
...
CALL MPI_SEND(darray, 10, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, ierr)
CALL MPI_BCAST(ival, 1, MPI_INT, 0, MPI_COMM_WORLD, ierr)
...
USE mpiinstead ofinclude "mpif.h".