[m-rev.] for review: C99 inline function bug fix

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Dec 21 18:25:53 AEDT 2001


Estimated hours taken: 2
Branches: main

Fix a bug reported by Michael Cameron <Michael.Cameron at general.monash.edu.au>,
where we were not handling inline functions correctly for C99.

runtime/mercury_std.h:
	- Document the MR_INLINE and MR_EXTERN_INLINE macros.
	- Fix a bug where MR_EXTERN_INLINE was defined wrongly for C99.
	- Add MR_OUTLINE_DEFN(), for providing out-of-line definitions
	  of inline functions declared with MR_EXTERN_INLINE; previously
	  this was done in a non-portable way that worked with GCC but
	  didn't work with C99.
	- Add MR_STATIC_INLINE, for inline functions used only within a
	  single translation unit -- currently not used, but should be
	  there for completeness.

runtime/mercury.c:
	Use MR_OUTLINE_DEFN() rather than #ifdef __GNUC__.

Workspace: /mnt/earth/home/earth/fjh/ws-earth4/mercury
Index: runtime/mercury_std.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_std.h,v
retrieving revision 1.18
diff -u -d -c -r1.18 mercury_std.h
cvs diff: conflicting specifications of output style
*** runtime/mercury_std.h	2001/07/26 14:49:03	1.18
--- runtime/mercury_std.h	2001/12/21 07:08:12
***************
*** 126,145 ****
  
  /*---------------------------------------------------------------------------*/
  
! /* Macros for inlining */
  
! #if defined(__GNUC__) 
    /* GNU C */
!   #define MR_INLINE __inline__
!   #define MR_EXTERN_INLINE extern __inline__
! #elif defined(__cplusplus) || __STDC_VERSION__ >= 199901
!   /* C++ or C99 */
!   #define MR_INLINE inline
!   #define MR_EXTERN_INLINE extern inline
  #else
    /* C89 */
!   #define MR_INLINE static
!   #define MR_EXTERN_INLINE static
  #endif
  
  /*---------------------------------------------------------------------------*/
--- 126,202 ----
  
  /*---------------------------------------------------------------------------*/
  
! /*
! ** Macros for inlining.
! **
! ** Inlining is treated differently by C++, C99, and GNU C.
! ** We also need to make it work for C89, which doesn't have
! ** any explicit support for inlining.
! **
! ** To make a function inline, you should declare it as either
! ** `MR_INLINE', `MR_EXTERN_INLINE', or `MR_STATIC_INLINE'.
! ** You should not use `extern' or `static' in combination with these macros.
! **
! ** `MR_STATIC_INLINE' should be used for functions that are defined and
! ** used only in a single translation unit (i.e. a single C source file).
! **
! ** If the inline function is to be used from more than one translation unit,
! ** then the function definition (not just declaration) should go in
! ** a header file, and you should use either MR_INLINE or MR_EXTERN_INLINE;
! ** the difference between these two is explained below.
! **
! ** MR_INLINE creates an inline definition of the function, and
! ** if needed it also creates an out-of-line definition of the function
! ** for the current translation unit, in case the function can't be inlined
! ** (e.g. because the function's address was taken, or because the
! ** file is compiled with the C compiler's optimizations turned off.)
! ** For C++, these definitions will be shared between different
! ** compilation units, but for C, each compilation unit that needs
! ** an out-of-line definition will gets its own definition.
! ** Generally that is not much of a problem, but if the C compiler
! ** doesn't optimize away such out-of-line definitions when they're
! ** not needed, this can get quite bad.
! **
! ** MR_EXTERN_INLINE creates an inline definition of the function,
! ** but it does NOT guarantee to create an out-of-line definition,
! ** even if one might be needed.  You need to explicitly provide
! ** an out-of-line definition for the function in one of the C files.
! ** This should be done using the MR_OUTLINE_DEFN(decl,body) macro,
! ** e.g. `MR_OUTLINE_DEFN(int foo(int x), { return x; })'.
! **
! ** The advantage of MR_EXTERN_INLINE is that it is more code-space-efficient,
! ** especially in the case where you are compiling with C compiler optimizations
! ** turned off.
! **
! ** It is OK to take the address of an inline function,
! ** but you should not assume that the address of a function declared
! ** MR_INLINE or MR_EXTERN_INLINE will be the same in all translation units.
! */
  
! #if defined(__cplusplus)
!   /* C++ */
!   #define MR_STATIC_INLINE		static inline
!   #define MR_INLINE			inline
!   #define MR_EXTERN_INLINE		inline
!   #define MR_OUTLINE_DEFN(DECL,BODY)
! #elif defined(__GNUC__) 
    /* GNU C */
!   #define MR_STATIC_INLINE		static __inline__
!   #define MR_INLINE			static __inline__
!   #define MR_EXTERN_INLINE		extern __inline__
!   #define MR_OUTLINE_DEFN(DECL,BODY)	DECL BODY
! #elif __STDC_VERSION__ >= 199901
!   /* C99 */
!   #define MR_STATIC_INLINE		static inline
!   #define MR_INLINE			static inline
!   #define MR_EXTERN_INLINE		inline
!   #define MR_OUTLINE_DEFN(DECL,BODY)	extern DECL;
  #else
    /* C89 */
!   #define MR_STATIC_INLINE		static
!   #define MR_INLINE			static
!   #define MR_EXTERN_INLINE		static
!   #define MR_OUTLINE_DEFN(DECL,BODY)
  #endif
  
  /*---------------------------------------------------------------------------*/
Index: runtime/mercury.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.c,v
retrieving revision 1.27
diff -u -d -r1.27 mercury.c
--- runtime/mercury.c	2001/12/07 07:53:44	1.27
+++ runtime/mercury.c	2001/12/21 07:14:58
@@ -817,65 +817,77 @@
 
 /*---------------------------------------------------------------------------*/
 
-#ifdef __GNUC__
-
 /*
 ** Provide definitions for functions declared `extern inline'.
 ** Note that this code duplicates the code in mercury.h/mercury_heap.h.
 */
-
-MR_Word
-MR_create1(MR_Word w1) 
-{
-	MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
-		1 * sizeof(MR_Word), "create1");
-	p[0] = w1;
-	return (MR_Word) p;
-}
 
-MR_Word
-MR_create2(MR_Word w1, MR_Word w2) 
-{
-	MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
-		2 * sizeof(MR_Word), "create2");
-	p[0] = w1;
-	p[1] = w2;
-	return (MR_Word) p;
-}
+MR_OUTLINE_DEFN(
+	MR_Word
+	MR_create1(MR_Word w1) 
+,
+	{
+		MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
+			1 * sizeof(MR_Word), "create1");
+		p[0] = w1;
+		return (MR_Word) p;
+	}
+)
 
-MR_Word
-MR_create3(MR_Word w1, MR_Word w2, MR_Word w3) 
-{
-	MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
-		3 * sizeof(MR_Word), "create3");
-	p[0] = w1;
-	p[1] = w2;
-	p[2] = w3;
-	return (MR_Word) p;
-}
+MR_OUTLINE_DEFN(
+	MR_Word
+	MR_create2(MR_Word w1, MR_Word w2) 
+,
+	{
+		MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
+			2 * sizeof(MR_Word), "create2");
+		p[0] = w1;
+		p[1] = w2;
+		return (MR_Word) p;
+	}
+)
 
-#ifdef MR_AVOID_MACROS
+MR_OUTLINE_DEFN(
+	MR_Word
+	MR_create3(MR_Word w1, MR_Word w2, MR_Word w3) 
+,
+	{
+		MR_Word *p = (MR_Word *) MR_new_object(MR_Word,
+			3 * sizeof(MR_Word), "create3");
+		p[0] = w1;
+		p[1] = w2;
+		p[2] = w3;
+		return (MR_Word) p;
+	}
+)
 
-MR_Box
-MR_box_float(MR_Float f)
-{
-	MR_Float *ptr;
+#if defined(MR_AVOID_MACROS) || !defined(__GNUC__)
 
-	MR_make_hp_float_aligned();
-	ptr = (MR_Float *) MR_new_object(MR_Float, sizeof(MR_Float), "float");
-	*ptr = f;
-	return (MR_Box) ptr;
-}
+MR_OUTLINE_DEFN(
+	MR_Box
+	MR_box_float(MR_Float f)
+,
+	{
+		MR_Float *ptr;
 
-MR_Float
-MR_unbox_float(MR_Box b)
-{
-	return *(MR_Float *)b;
-}
+		MR_make_hp_float_aligned();
+		ptr = (MR_Float *) MR_new_object(MR_Float, sizeof(MR_Float),
+			"float");
+		*ptr = f;
+		return (MR_Box) ptr;
+	}
+)
 
-#endif /* MR_AVOID_MACROS */
+MR_OUTLINE_DEFN(
+	MR_Float
+	MR_unbox_float(MR_Box b)
+,
+	{
+		return *(MR_Float *)b;
+	}
+)
 
-#endif /* __GNUC__ */
+#endif /* MR_AVOID_MACROS || !__GNUC__ */
 
 /*
 ** This is exactly the same as MR_box_float(), except that

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list