Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Open MPI User's mailing list

Subject: Re: [OMPI users] Can't compile C++ program with extern "C" { #include mpi.h }
From: Adam C Powell IV (hazelsct_at_[hidden])
Date: 2008-01-30 17:35:39


Hello,

With no reply in a couple of weeks, I'm wondering if my previous message
got dropped. (Then again, my previous message was a couple of weeks
late in replying to its predecessor...)

I'm recommending a change to mpi.h which would let C headers included by
C++ programs do:
#define OMPI_SKIP_MPICXX
#include <mpi.h>
#undef OMPI_SKIP_MPICXX
without preventing the C++ headers from being included at another time.
See below for the recommended change.

Cheers,
Adam

On Sun, 2008-01-13 at 16:02 -0500, Adam C Powell IV wrote:
> Hi again,
>
> Sorry about the hiatus; I thought "Great, my OMPI_SKIP_CXX hack works"
> and didn't check to see your reply, even though it came right away.
>
> On Tue, 2008-01-01 at 11:07 -0700, Brian Barrett wrote:
> > On Jan 1, 2008, at 12:47 AM, Adam C Powell IV wrote:
> >
> > > On Mon, 2007-12-31 at 20:01 -0700, Brian Barrett wrote:
> > >>
> > >>
> > >> Yeah, this is a complicated example, mostly because HDF5 should
> > >> really be covering this problem for you. I think your only option at
> > >> that point would be to use the #define to not include the C++ code.
> > >>
> > >> The problem is that the MPI standard *requires* mpi.h to include both
> > >> the C and C++ interface declarations if you're using C++. There's no
> > >> way for the preprocessor to determine whether there's a currently
> > >> active extern "C" block, so there's really not much we can do. Best
> > >> hope would be to get the HDF5 guys to properly protect their code
> > >> from C++...
> > >
> > > Okay. So in HDF5, since they call MPI from C, they're just using
> > > the C
> > > interface, right? So should they define OMPI_SKIP_MPICXX just in case
> > > they're #included by C++ and using OpenMPI, or is there a more MPI
> > > implementation-agnostic way to do it?
> >
> >
> > No, they should definitely not be disabling the C++bindings inside
> > HDF5 -- that would be a situation worse than the current one.
> > Consider the case where an application uses both HDF5 and the C++ MPI
> > bindings. It includes hdf5.h before mpi.h. The hdf5.h includes
> > mpi.h, without the C++ bindings. The application then includes mpi.h,
> > wanting the C++ bindings. But the multiple inclusion protection in
> > mpi.h means nothing happens, so no C++ bindings.
>
> I agree, that would be a problem...
>
> > My comment about HDF5 was that it would be easiest if it protected its
> > declarations with extern "C" when using C++. This is what most
> > packages that might be used with C++ do, and it works pretty well.
> > I'd actually be surprised if modern versions of HDF5 didn't already do
> > that.
> >
> > Now that it's not New Years eve, I thought of what's probably the
> > easiest solution for you. Just include mpi.h (outside your extern "C"
> > block) before hdf5.h. The multiple inclusion protection in mpi.h will
> > mean that the preprocessor removes everything from the mpi.h that's
> > included from hdf5.h. So the extern "C" around the hdf5.h shouldn't
> > be too much of a problem.
>
> That almost works. But not quite. :-(
>
> If I put that in my C++ files or headers, that would be fine.
> Unfortunately, the program I'm porting has:
>
> A.h:
> #include <hdf5.h>
>
> B.hxx:
> extern "C" { #include "A.h" }
>
> And then C.hxx, D.cxx, etc. all include B.hxx, and E.h and F.c include
> A.h. So if I just add "#include <mpi.h>" to A.h before hdf5, I have the
> same problem: #including <mpi.h> within an extern "C" block.
>
> The only way to work around this is to patch B, C, D, E and F. Very bad.
> It shouldn't have to be this way.
>
> Here's a way to make it work, but it requires a patch to OpenMPI mpi.h:
> --- /usr/include/mpi/mpi.h~ 2008-01-10 17:26:15.000000000 -0500
> +++ /usr/include/mpi/mpi.h 2008-01-13 15:57:45.000000000 -0500
> @@ -1770,6 +1770,8 @@
> }
> #endif
>
> +#endif /* OMPI_MPI_H */
> +
> /*
> * Conditional MPI 2 C++ bindings support. Include if:
> * - The user does not explicitly request us to skip it (when a C++ compiler
> @@ -1783,5 +1785,3 @@
> #include "openmpi/ompi/mpi/cxx/mpicxx.h"
> #endif
> #endif
> -
> -#endif /* OMPI_MPI_H */
>
> Then hdf5.h, or this app's A.h, or whoever, can do:
> #define OMPI_SKIP_MPICXX
> #include <mpi.h> or <hdf5.h> or <A.h> etc.
> #undef OMPI_SKIP_MPICXX
> and the C++ programs which include this will not miss their C++ headers,
> because they won't be inside the OMPI_MPI_H #ifdef protection. But they
> also won't get them twice, because they'll be in the MPIPP_H #ifdef.
>
> Do you have any other ideas? Or will this or something like it be
> necessary to protect against arbitrarily nested #includes from C++
> extern "C" blocks, without stepping on the C++ prototypes?
>
> Thanks again for your help,
> -Adam

-- 
GPG fingerprint: D54D 1AEE B11C CE9B A02B  C5DD 526F 01E8 564E E4B6
Engineering consulting with open source tools
http://www.opennovation.com/