Following the discussion about ABI compatibility and type-punning of non client-visible types, I've attached a patch against 1.3.2 which casts to an opaque (void *) when OMPI_BUILDING is 0.

This will prevent the compiler from trying to do any strict-aliasing based optimizations when the definition of the type to cast to is unknown.

When builing Open MPI, the (void *) cast is omitted (because of the compiler flag "-DOMPI_BUILDING=1") and the code remains as before.

This clears up all warnings for my GCC 4.1 compiler.

Simon.

>> Ultimately, for internal use, the (void *) is bad, but from client
>> code
>> with no knowledge of your types, it should be mandatory and tells the
>> compiler to make no assumptions about aliasing.
>>
>
> I think you're convincing me, but I need to think over this a little
> more.
>
> I wonder if we should have a "smart" #define for MPI_COMM_WORLD that
> puts the (void*) in when compiling user codes, and doesn't include it
> when building OMPI itself (i.e., so that we can get the debugging
> benefit of proper type checking when building OMPI). We do have the
> OMPI_BUILDING macro in opal_config_bottom.h that could be used to
> switch the macro definition. Hrm...
diff -r -U 5 openmpi-1.3.2.orig/ompi/include/mpi.h.in openmpi-1.3.2.patched/ompi/include/mpi.h.in
--- openmpi-1.3.2.orig/ompi/include/mpi.h.in	2009-04-16 20:02:42.000000000 +0100
+++ openmpi-1.3.2.patched/ompi/include/mpi.h.in	2009-04-30 12:50:27.000000000 +0100
@@ -190,10 +190,23 @@
 #define MPIO_Request MPI_Request
 #define MPIO_Test MPI_Test
 #define MPIO_Wait MPI_Wait
 #endif

+/*
+ * When initializing global pointers to Open MPI internally-defined
+ * structs, some compilers warn about type-punning to incomplete types.
+ * Therefore, when full struct definitions are unavailable (when not
+ * building Open MPI), cast to an opaque void * pointer to disable
+ * any strict-aliasing optimizations.
+ */
+#if !OMPI_BUILDING
+#define OMPI_PREDEFINED_GLOBAL( type, global ) ( (type)((void *)&(global)) )
+#else
+#define OMPI_PREDEFINED_GLOBAL( type, global ) ( (type)&(global) )
+#endif
+
 #if defined(c_plusplus) || defined(__cplusplus)
 extern "C" {
 #endif
 /*
  * Typedefs
@@ -478,19 +491,19 @@
 };

 /*
  * NULL handles
  */
-#define MPI_GROUP_NULL (((MPI_Group)&(ompi_mpi_group_null)))
-#define MPI_COMM_NULL (((MPI_Comm)&(ompi_mpi_comm_null)))
-#define MPI_REQUEST_NULL (((MPI_Request)&(ompi_request_null)))
-#define MPI_OP_NULL (((MPI_Op)&(ompi_mpi_op_null)))
-#define MPI_ERRHANDLER_NULL (((MPI_Errhandler)&(ompi_mpi_errhandler_null)))
-#define MPI_INFO_NULL (((MPI_Info)&(ompi_mpi_info_null)))
-#define MPI_WIN_NULL (((MPI_Win)&(ompi_mpi_win_null)))
+#define MPI_GROUP_NULL OMPI_PREDEFINED_GLOBAL(MPI_Group, ompi_mpi_group_null)
+#define MPI_COMM_NULL OMPI_PREDEFINED_GLOBAL(MPI_Comm, ompi_mpi_comm_null)
+#define MPI_REQUEST_NULL OMPI_PREDEFINED_GLOBAL(MPI_Request, ompi_request_null)
+#define MPI_OP_NULL OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_null)
+#define MPI_ERRHANDLER_NULL OMPI_PREDEFINED_GLOBAL(MPI_Errhandler, ompi_mpi_errhandler_null)
+#define MPI_INFO_NULL OMPI_PREDEFINED_GLOBAL(MPI_Info, ompi_mpi_info_null)
+#define MPI_WIN_NULL OMPI_PREDEFINED_GLOBAL(MPI_Win, ompi_mpi_win_null)
 #if OMPI_PROVIDE_MPI_FILE_INTERFACE
-#define MPI_FILE_NULL (((MPI_File)&(ompi_mpi_file_null)))
+#define MPI_FILE_NULL OMPI_PREDEFINED_GLOBAL(MPI_File, ompi_mpi_file_null)
 #endif

 #define MPI_STATUS_IGNORE ((MPI_Status *) 0)
 #define MPI_STATUSES_IGNORE ((MPI_Status *) 0)

@@ -714,121 +727,121 @@
 OMPI_DECLSPEC extern MPI_Fint *MPI_F_STATUSES_IGNORE;

 /*
  * MPI predefined handles
  */
-#define MPI_COMM_WORLD (((MPI_Comm)&(ompi_mpi_comm_world)))
-#define MPI_COMM_SELF (((MPI_Comm)&(ompi_mpi_comm_self)))
+#define MPI_COMM_WORLD OMPI_PREDEFINED_GLOBAL( MPI_Comm, ompi_mpi_comm_world)
+#define MPI_COMM_SELF OMPI_PREDEFINED_GLOBAL(MPI_Comm, ompi_mpi_comm_self)

-#define MPI_GROUP_EMPTY (((MPI_Group)&(ompi_mpi_group_empty)))
+#define MPI_GROUP_EMPTY OMPI_PREDEFINED_GLOBAL(MPI_Group, ompi_mpi_group_empty)

-#define MPI_MAX (((MPI_Op)&(ompi_mpi_op_max)))
-#define MPI_MIN (((MPI_Op)&(ompi_mpi_op_min)))
-#define MPI_SUM (((MPI_Op)&(ompi_mpi_op_sum)))
-#define MPI_PROD (((MPI_Op)&(ompi_mpi_op_prod)))
-#define MPI_LAND (((MPI_Op)&(ompi_mpi_op_land)))
-#define MPI_BAND (((MPI_Op)&(ompi_mpi_op_band)))
-#define MPI_LOR (((MPI_Op)&(ompi_mpi_op_lor)))
-#define MPI_BOR (((MPI_Op)&(ompi_mpi_op_bor)))
-#define MPI_LXOR (((MPI_Op)&(ompi_mpi_op_lxor)))
-#define MPI_BXOR (((MPI_Op)&(ompi_mpi_op_bxor)))
-#define MPI_MAXLOC (((MPI_Op)&(ompi_mpi_op_maxloc)))
-#define MPI_MINLOC (((MPI_Op)&(ompi_mpi_op_minloc)))
-#define MPI_REPLACE (((MPI_Op)&(ompi_mpi_op_replace)))
+#define MPI_MAX OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_max)
+#define MPI_MIN OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_min)
+#define MPI_SUM OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_sum)
+#define MPI_PROD OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_prod)
+#define MPI_LAND OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_land)
+#define MPI_BAND OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_band)
+#define MPI_LOR OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_lor)
+#define MPI_BOR OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_bor)
+#define MPI_LXOR OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_lxor)
+#define MPI_BXOR OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_bxor)
+#define MPI_MAXLOC OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_maxloc)
+#define MPI_MINLOC OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_minloc)
+#define MPI_REPLACE OMPI_PREDEFINED_GLOBAL(MPI_Op, ompi_mpi_op_replace)

 /* C datatypes */
-#define MPI_DATATYPE_NULL (((MPI_Datatype)&(ompi_mpi_datatype_null)))
-#define MPI_BYTE (((MPI_Datatype)&(ompi_mpi_byte)))
-#define MPI_PACKED (((MPI_Datatype)&(ompi_mpi_packed)))
-#define MPI_CHAR (((MPI_Datatype)&(ompi_mpi_char)))
-#define MPI_SHORT (((MPI_Datatype)&(ompi_mpi_short)))
-#define MPI_INT (((MPI_Datatype)&(ompi_mpi_int)))
-#define MPI_LONG (((MPI_Datatype)&(ompi_mpi_long)))
-#define MPI_FLOAT (((MPI_Datatype)&(ompi_mpi_float)))
-#define MPI_DOUBLE (((MPI_Datatype)&(ompi_mpi_double)))
-#define MPI_LONG_DOUBLE (((MPI_Datatype)&(ompi_mpi_long_double)))
-#define MPI_UNSIGNED_CHAR (((MPI_Datatype)&(ompi_mpi_unsigned_char)))
-#define MPI_SIGNED_CHAR (((MPI_Datatype)&(ompi_mpi_signed_char)))
-#define MPI_UNSIGNED_SHORT (((MPI_Datatype)&(ompi_mpi_unsigned_short)))
-#define MPI_UNSIGNED_LONG (((MPI_Datatype)&(ompi_mpi_unsigned_long)))
-#define MPI_UNSIGNED (((MPI_Datatype)&(ompi_mpi_unsigned)))
-#define MPI_FLOAT_INT (((MPI_Datatype)&(ompi_mpi_float_int)))
-#define MPI_DOUBLE_INT (((MPI_Datatype)&(ompi_mpi_double_int)))
-#define MPI_LONG_DOUBLE_INT (((MPI_Datatype)&(ompi_mpi_longdbl_int)))
-#define MPI_LONG_INT (((MPI_Datatype)&(ompi_mpi_long_int)))
-#define MPI_SHORT_INT (((MPI_Datatype)&(ompi_mpi_short_int)))
-#define MPI_2INT (((MPI_Datatype)&(ompi_mpi_2int)))
-#define MPI_UB (((MPI_Datatype)&(ompi_mpi_ub)))
-#define MPI_LB (((MPI_Datatype)&(ompi_mpi_lb)))
-#define MPI_WCHAR (((MPI_Datatype)&(ompi_mpi_wchar)))
+#define MPI_DATATYPE_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_datatype_null)
+#define MPI_BYTE OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_byte)
+#define MPI_PACKED OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_packed)
+#define MPI_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_char)
+#define MPI_SHORT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_short)
+#define MPI_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
+#define MPI_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long)
+#define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
+#define MPI_DOUBLE OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_double)
+#define MPI_LONG_DOUBLE OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_double)
+#define MPI_UNSIGNED_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_unsigned_char)
+#define MPI_SIGNED_CHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_signed_char)
+#define MPI_UNSIGNED_SHORT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_unsigned_short)
+#define MPI_UNSIGNED_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_unsigned_long)
+#define MPI_UNSIGNED OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_unsigned)
+#define MPI_FLOAT_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float_int)
+#define MPI_DOUBLE_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_double_int)
+#define MPI_LONG_DOUBLE_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_longdbl_int)
+#define MPI_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_int)
+#define MPI_SHORT_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_short_int)
+#define MPI_2INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2int)
+#define MPI_UB OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_ub)
+#define MPI_LB OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_lb)
+#define MPI_WCHAR OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_wchar)
 #if OMPI_HAVE_LONG_LONG
-#define MPI_LONG_LONG_INT (((MPI_Datatype)&(ompi_mpi_long_long_int)))
-#define MPI_LONG_LONG (((MPI_Datatype)&(ompi_mpi_long_long_int)))
-#define MPI_UNSIGNED_LONG_LONG (((MPI_Datatype)&(ompi_mpi_unsigned_long_long)))
+#define MPI_LONG_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int)
+#define MPI_LONG_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int)
+#define MPI_UNSIGNED_LONG_LONG OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_unsigned_long_long)
 #endif  /* OMPI_HAVE_LONG_LONG */
-#define MPI_2COMPLEX (((MPI_Datatype)&(ompi_mpi_2cplex)))
-#define MPI_2DOUBLE_COMPLEX (((MPI_Datatype)&(ompi_mpi_2dblcplex)))
+#define MPI_2COMPLEX OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2cplex)
+#define MPI_2DOUBLE_COMPLEX OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2dblcplex)

 /* Fortran datatype bindings */
-#define MPI_CHARACTER (((MPI_Datatype)&(ompi_mpi_character)))
-#define MPI_LOGICAL (((MPI_Datatype)&(ompi_mpi_logic)))
+#define MPI_CHARACTER OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_character)
+#define MPI_LOGICAL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_logic)
 #if OMPI_HAVE_FORTRAN_LOGICAL1
-#define MPI_LOGICAL1 (((MPI_Datatype)&(ompi_mpi_logical1)))
+#define MPI_LOGICAL1 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_logical1)
 #endif
 #if OMPI_HAVE_FORTRAN_LOGICAL2
-#define MPI_LOGICAL2 (((MPI_Datatype)&(ompi_mpi_logical2)))
+#define MPI_LOGICAL2 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_logical2)
 #endif
 #if OMPI_HAVE_FORTRAN_LOGICAL4
-#define MPI_LOGICAL4 (((MPI_Datatype)&(ompi_mpi_logical4)))
+#define MPI_LOGICAL4 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_logical4)
 #endif
 #if OMPI_HAVE_FORTRAN_LOGICAL8
-#define MPI_LOGICAL8 (((MPI_Datatype)&(ompi_mpi_logical8)))
+#define MPI_LOGICAL8 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_logical8)
 #endif
-#define MPI_INTEGER (((MPI_Datatype)&(ompi_mpi_integer)))
+#define MPI_INTEGER OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer)
 #if OMPI_HAVE_FORTRAN_INTEGER1
-#define MPI_INTEGER1 (((MPI_Datatype)&(ompi_mpi_integer1)))
+#define MPI_INTEGER1 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer1)
 #endif
 #if OMPI_HAVE_FORTRAN_INTEGER2
-#define MPI_INTEGER2 (((MPI_Datatype)&(ompi_mpi_integer2)))
+#define MPI_INTEGER2 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer2)
 #endif
 #if OMPI_HAVE_FORTRAN_INTEGER4
-#define MPI_INTEGER4 (((MPI_Datatype)&(ompi_mpi_integer4)))
+#define MPI_INTEGER4 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer4)
 #endif
 #if OMPI_HAVE_FORTRAN_INTEGER8
-#define MPI_INTEGER8 (((MPI_Datatype)&(ompi_mpi_integer8)))
+#define MPI_INTEGER8 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer8)
 #endif
 #if OMPI_HAVE_FORTRAN_INTEGER16
-#define MPI_INTEGER16 (((MPI_Datatype)&(ompi_mpi_integer16)))
+#define MPI_INTEGER16 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_integer16)
 #endif
-#define MPI_REAL (((MPI_Datatype)&(ompi_mpi_real)))
+#define MPI_REAL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_real)
 #if OMPI_HAVE_FORTRAN_REAL4
-#define MPI_REAL4 (((MPI_Datatype)&(ompi_mpi_real4)))
+#define MPI_REAL4 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_real4)
 #endif
 #if OMPI_HAVE_FORTRAN_REAL8
-#define MPI_REAL8 (((MPI_Datatype)&(ompi_mpi_real8)))
+#define MPI_REAL8 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_real8)
 #endif
 #if OMPI_HAVE_FORTRAN_REAL16
-#define MPI_REAL16 (((MPI_Datatype)&(ompi_mpi_real16)))
+#define MPI_REAL16 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_real16)
 #endif
-#define MPI_DOUBLE_PRECISION (((MPI_Datatype)&(ompi_mpi_dblprec)))
-#define MPI_COMPLEX (((MPI_Datatype)&(ompi_mpi_cplex)))
+#define MPI_DOUBLE_PRECISION OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_dblprec)
+#define MPI_COMPLEX OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_cplex)
 #if OMPI_HAVE_FORTRAN_REAL4
-#define MPI_COMPLEX8 (((MPI_Datatype)&(ompi_mpi_complex8)))
+#define MPI_COMPLEX8 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_complex8)
 #endif
 #if OMPI_HAVE_FORTRAN_REAL8
-#define MPI_COMPLEX16 (((MPI_Datatype)&(ompi_mpi_complex16)))
+#define MPI_COMPLEX16 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_complex16)
 #endif
 #if OMPI_HAVE_FORTRAN_REAL16
-#define MPI_COMPLEX32 (((MPI_Datatype)&(ompi_mpi_complex32)))
+#define MPI_COMPLEX32 OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_complex32)
 #endif
-#define MPI_DOUBLE_COMPLEX (((MPI_Datatype)&(ompi_mpi_dblcplex)))
-#define MPI_2REAL (((MPI_Datatype)&(ompi_mpi_2real)))
-#define MPI_2DOUBLE_PRECISION (((MPI_Datatype)&(ompi_mpi_2dblprec)))
-#define MPI_2INTEGER (((MPI_Datatype)&(ompi_mpi_2integer)))
+#define MPI_DOUBLE_COMPLEX OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_dblcplex)
+#define MPI_2REAL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2real)
+#define MPI_2DOUBLE_PRECISION OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2dblprec)
+#define MPI_2INTEGER OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2integer)

-#define MPI_ERRORS_ARE_FATAL (((MPI_Errhandler)&(ompi_mpi_errors_are_fatal)))
-#define MPI_ERRORS_RETURN (((MPI_Errhandler)&(ompi_mpi_errors_return)))
+#define MPI_ERRORS_ARE_FATAL OMPI_PREDEFINED_GLOBAL(MPI_Errhandler, ompi_mpi_errors_are_fatal)
+#define MPI_ERRORS_RETURN OMPI_PREDEFINED_GLOBAL(MPI_Errhandler, ompi_mpi_errors_return)

 /* Typeclass definition for MPI_Type_match_size */
 #define MPI_TYPECLASS_INTEGER    1
 #define MPI_TYPECLASS_REAL       2
 #define MPI_TYPECLASS_COMPLEX    3
Only in openmpi-1.3.2.patched/ompi/include: mpi.h.in~

Reply via email to