Open MPI logo

Open MPI Development Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Development mailing list

Subject: [OMPI devel] predefined ompi_t types break strict-aliasing rules
From: Number Cruncher (number.cruncher_at_[hidden])
Date: 2009-04-24 08:08:58


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