Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |  

This web mail archive is frozen.

This page is part of a frozen web archive of this mailing list.

You can still navigate around this archive, but know that no new mails have been added to it since July of 2016.

Click here to be taken to the new web archives of this list; it includes all the mails that are in this frozen archive plus all new mails that have been sent to the list since it was migrated to the new archives.

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-13 16:02:51


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/