With, or without, C++ bindings, I'm getting serious warnings when
compiling *any* C++ program which #includes <mpi.h>:
Program (helloMPI.cpp):
#include <iostream>
#include <mpi.h>
int
main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int myRank;
if(!MPI_Comm_rank(MPI_COMM_WORLD, &myRank)) {
std::cout << "Hello World from " << myRank << std::endl;
}
MPI_Finalize();
return 0;
}
Compiler (g++ 4.1.2) output when using optimization (-O2):
/opt/cfs/include/openmpi/ompi/mpi/cxx/datatype.h: In constructor
‘MPI::Datatype::Datatype()’:
/opt/cfs/include/openmpi/ompi/mpi/cxx/datatype.h:68: warning:
type-punning to incomplete type might break strict-aliasing rules
/opt/cfs/include/openmpi/ompi/mpi/cxx/request.h: In constructor
‘MPI::Request::Request()’:
/opt/cfs/include/openmpi/ompi/mpi/cxx/request.h:60: warning:
type-punning to incomplete type might break strict-aliasing rules
/opt/cfs/include/openmpi/ompi/mpi/cxx/group.h: In constructor
‘MPI::Group::Group()’:
/opt/cfs/include/openmpi/ompi/mpi/cxx/group.h:61: warning: type-punning
to incomplete type might break strict-aliasing rules
....... [many more]
Without the C++ bindings, I still get:
helloMPI.cpp: In function ‘int main(int, char**)’:
helloMPI.cpp:8: warning: type-punning to incomplete type might break
strict-aliasing rules
I've followed the discussion at ompi/communicator/communicator.h and
looked at the major changeset at
https://svn.open-mpi.org/trac/ompi/changeset/20627 .
The problem is that, with optimization enabled, the compiler can assume
that "an object of one type is assumed never to reside at the same
address as an object of a different type, unless the types are almost
the same" (gcc info page). In this case ompi_predefined_*_t are not
fully defined by the time the C++ compiler expands the macro
MPI_COMM_WORLD to:
((ompi_communicator_t *)&(ompi_mpi_comm_world))
The compiler complains because ompi_mpi_comm_world is declared as an
"extern struct ompi_predefined_communicator_t" but the type is
incomplete, so it can't tell whether the cast is a permissible
almost-the-same type pun (e.g. an "int" can alias an "unsigned").
I think this is potentially a serious performance issue for anyone using
OpenMPI in a C++ environment, and the profuse warnings preclude it's use
in our build system.
The bad news is that the only work around I have is to insert (void *)
casts between (MPI_TYPENAME) and the address operator, e.g.:
#define MPI_COMM_WORLD (((MPI_Comm)(void *)&(ompi_mpi_comm_world)))
An alternative might be to make the full type definition available by
#including some of the internal developer headers such as
ompi/communicator/communicator.h