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/

Reply via email to