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



Reply via email to