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/