glib's inline macros (Re: [PATCH]...)



On 4 Dec 2000, Owen Taylor wrote:

> Darin Adler <darin eazel com> writes:

> > > +static inline guint
> > > +translate_state (guint xstate)
> > > +{
> > > +  return xstate & ~GDK_RELEASE_MASK;
> > > +}
> > > +
> > 
> > Shouldn't this use G_INLINE_FUNC instead of inline?
> 
> No. To quote from the glib header file:
> 
> /* inlining hassle. for compilers that don't allow the `inline' keyword,
>  * mostly because of strict ANSI C compliance or dumbness, we try to fall
>  * back to either `__inline__' or `__inline'.
>  * we define G_CAN_INLINE, if the compiler seems to be actually
>  * *capable* to do function inlining, in which case inline function bodys
>  * do make sense. we also define G_INLINE_FUNC to properly export the
>  * function prototypes if no inlining can be performed.
>  * we special case most of the stuff, so inline functions can have a normal
>  * implementation by defining G_INLINE_FUNC to extern and G_CAN_INLINE to 1.
>  */
> #ifndef G_INLINE_FUNC
[...]

> Clear as day right? But the basic jist of that is that 'inline'
> will always be defined and 'static inline' is the right thing
> to use for an inline function within a file, while
> G_INLINE_FUNC is more like GCC's 'extern inline'.

it's even worse in 1.3 ;)
though, i tried to improve the comment and usage there:

/* inlining hassle. for compilers that don't allow the `inline' keyword,
 * mostly because of strict ANSI C compliance or dumbness, we try to fall
 * back to either `__inline__' or `__inline'.
 * we define G_CAN_INLINE, if the compiler seems to be actually
 * *capable* to do function inlining, in which case inline function bodys
 * do make sense. we also define G_INLINE_FUNC to properly export the
 * function prototypes if no inlining can be performed.
 * inline function bodies have to be special cased with G_CAN_INLINE and a
 * .c file specific macro to allow one compiled instance with extern linkage
 * of the functions by defining G_IMPLEMENT_INLINES and the .c file macro.
 */

there are two cases inline is being used:

a) declaration of inline functions within a .c files,
   here, glib makes sure the keyword "inline" always exists
   and does the right (possible) thing:

static inline void
my_func (void)
{
  /* stuff */
}

b) declaration of inline functions in public header files.
   here we want user code that includes our header file to see
   the function definition as if it were an inline function
   of type (a), unless the compiler can't inline. in that case
   we want the user code to see a normal prototype and link against
   a compiled version that we provided with our header file.
   for that we need two things in the header file, a prototype
   and an actuall function body, embedded in macros provided
   by the above INLINE macro magics:

glib.h:

G_INLINE_FUNC void      g_trash_stack_push      (GTrashStack **stack_p,
                                                 gpointer      data_p);

#if defined (G_CAN_INLINE) || defined (__G_UTILS_C__)

G_INLINE_FUNC gint
g_bit_nth_lsf (guint32 mask,
               gint    nth_bit)
{
  do
    {
      nth_bit++;
      if (mask & (1 << (guint) nth_bit))
        return nth_bit;
    }
  while (nth_bit < 32);
  return -1;
}

#endif  /* G_CAN_INLINE || __G_UTILS_C__ */

then, the only additional thing we need to do is to provide a
compiled version of that function, that user code can link against
for retarded compilers:

gutils.c:

/* implement Glib's inline functions
 */
#define G_IMPLEMENT_INLINES 1
#define __G_UTILS_C__
#include "glib.h"

does that clear things up?
    

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]