Re: can someone explain "inline" once and for all?

Previous thread: [RFC] [PATCH] Power S3 Resume Optimization Patch. Request for Comment by Seshadri, Harinarayanan on Friday, January 19, 2007 - 1:08 am. (4 messages)

Next thread: Re: [linux-usb-devel] 2.6.20-rc4: usb somehow broken by Prakash Punnoor on Friday, January 19, 2007 - 7:00 am. (1 message)
From: Robert P. J. Day
Date: Friday, January 19, 2007 - 4:56 am

apologies if this is an inappropriately trivial question but this
has been bugging me for a while.  what is the deal with "inline"?

  first, there appear to be three possible ways of specifying an
inline routine in the kernel source:

  $ grep -r "static inline " .
  $ grep -r "static __inline__ " .
  $ grep -r "static __inline " .

i vaguely recall that this has something to do with a distinction
between C99 inline and gcc inline and trying to avoid a clash between
the two, but i'm not going to put any money on that.  but the
confusion probably explains why so many people insist on creating new
macros to represent inline:

  $ grep -r "#define.*inline" .

is there a simple explanation for how to *properly* define inline
routines in the kernel?  and maybe this can be added to the
CodingStyle guide (he mused, wistfully).

rdau

-

From: Pekka Enberg
Date: Friday, January 19, 2007 - 6:01 am

AFAIK __always_inline is the only reliable way to force inlining where
it matters for correctness (for example, when playing tricks with
__builtin_return_address like we do in the slab).

Anything else is just a hint to the compiler that might be ignored if
the optimizer thinks it knows better.
-

From: Robert P. J. Day
Date: Friday, January 19, 2007 - 6:19 am

oh, *that* part i knew.  what i don't understand is the difference
between "inline", "__inline" and "__inline__".  you can see in
include/linux/compiler-gcc4.h:

#ifdef CONFIG_FORCED_INLINING
# undef inline
# undef __inline__
# undef __inline
# define inline                 inline          __attribute__((always_inline))
# define __inline__             __inline__      __attribute__((always_inline))
# define __inline               __inline        __attribute__((always_inline))
#endif

  so that header file certainly suggests that there's some sort of
difference.  after which it gets even more confusing as various macros
seem to mix and match:

  drivers/cdrom/sbpcd.c:#define INLINE inline
  arch/arm/nwfpe/ARM-gcc.h:#define INLINE extern __inline__
  arch/cris/arch-v10/kernel/fasttimer.c:#define __INLINE__ inline
  arch/alpha/mm/fault.c:#define __EXTERN_INLINE inline
  ... etc etc ...

  i mean, how many different kinds of inline *are* there?

rday

p.s.  apparently, some of the alpha people are less than thrilled with
the situation:

include/asm-alpha/compiler.h:
-----------------------------

#ifdef __KERNEL__
/* Some idiots over in <linux/compiler.h> thought inline should imply
   always_inline.  This breaks stuff.  We'll include this file whenever
   we run into such problems.  */

#include <linux/compiler.h>
#undef inline
#undef __inline__
#undef __inline
#undef __always_inline
#define __always_inline         inline __attribute__((always_inline))

#endif /* __KERNEL__ */




-

From: Adrian Bunk
Date: Friday, January 19, 2007 - 7:13 am

With the current implementation in the kernel (and considering that 
CONFIG_FORCED_INLINING was implemented in a way that it never had any 
effect), __always_inline and inline are currently equivalent.

__always_inline is mostly an annotation that really bad things might 
happen if the code doesn't get inlined.

But I'm not sure whether such a distinction is required at all - the 
rule of thumb should be that static functions in headers should be 
inline (otherwise, they belong into a C file), and functions in C files 
should never be marked inline. [1]

cu
Adrian

[1] For the latter there might be a handful of exceptions in the whole 
    kernel in real fastpath code, but usually gcc knows best when to 
    inline a function - and we have a global CONFIG_CC_OPTIMIZE_FOR_SIZE 
    knob for influencing the decision.

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

-

From: Robert P. J. Day
Date: Friday, January 19, 2007 - 7:44 am

right, and that last part explains that snippet i previously posted
from include/asm-alpha/compiler.h

========================
#ifdef __KERNEL__
/* Some idiots over in <linux/compiler.h> thought inline should imply
   always_inline.  This breaks stuff.  We'll include this file whenever
   we run into such problems.  */
========================

  which is a result of this from include/linux/compiler.h:

========================

#define inline          inline          __attribute__((always_inline))
#define __inline__      __inline__      __attribute__((always_inline))
#define __inline        __inline        __attribute__((always_inline))

which certainly seems to suggest that *ever* explicitly stating
"always inline" is redundant, no?  maybe i'm missing something

and that makes sense.  it has no effect, it's more for just
commenting.  but it's still kind of misleading.

rday
-

From: Andreas Schwab
Date: Friday, January 19, 2007 - 6:37 am

No, it doesn't (there is no C99 compatible inline in gcc before 4.3).  It
has to do with the fact that inline is not a keyword in C89, so you need
to use a different spelling when you want to stay compatible with strict
C89.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Robert P. J. Day
Date: Friday, January 19, 2007 - 6:48 am

ok, so based on that and a bit more surfing, i see that either
"__inline" or "__inline__" are acceptable variants in gcc, and there
is no distinction between them, is that right?

but in terms of strict C89 compatibility, it would seem to be a bit
late for that given:

  $ grep -r "static inline " .

no?

rday
-

From: Andreas Schwab
Date: Friday, January 19, 2007 - 6:58 am

The kernel does not use strict C89, it uses GNUC89.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Robert P. J. Day
Date: Friday, January 19, 2007 - 7:00 am

in that case, why did you just waste my time and all that bandwidth
by writing in your previous post:

"... so you need to use a different spelling when you want to stay
compatible with strict C89."

  please do me a favour and don't post another reply until you go back
and actually read my original question.

rday
-

From: Alexandre Oliva
Date: Friday, January 19, 2007 - 10:15 am

inline, __inline and __inline__ are equivalent as far as GCC is

I suspect you're thinking of a different issue.

In C99, static inline means the same as in GNU89, non-static
non-extern inline means 'use this definition, that does not define
objects with static storage nor references identifiers with internal
linkage, for inlining or for a local definition, but make calls to it
fast and don't generate any out-of-line definition', and extern inline
means 'compile this code into a global out-of-line function, but also
inline it wherever it makes sense'.

In GNU89, static inline means 'compile this code into a local
out-of-line function if needed, but also inline it wherever it makes
sense', non-static non-extern inline means 'compile this code into a
global out-of-line function, but also inline it wherever it makes
sense', and extern inline means 'use this definition for inlining, but
don't generate any out-of-line definition; because either I have a
non-inline definition in this or in another translation unit, or I
want undefined-symbol errors at link time if inlining fails.'

So you see that the meaning of extern inline and non-extern inline are
also reversed comparing GNU89 with C99.  That's quite unfortunate,
and GNU libc went to some trouble to encapsulate the intended inline
meaning into preprocessor macros even in user headers, such that the
intended meaning is obtained regardless of the compiler version.

Fortunately, static inline is probably the most useful and thus common
case anyway.  Other constructs will work as in GNU89 up to GCC 4.3,
even with -std=c99, but the meaning of inline in C99 and GNU99 is
intended to be fixed to the C99 semantics in GCC 4.4, according to
http://gcc.gnu.org/ml/gcc/2006-11/msg00006.html

That's still a long way ahead (the 4.3 development cycle has just
started), but it wouldn't hurt to start fixing incompatibilities
sooner rather than later, and coming up with a clean and uniform set
of inline macros that express intended meaning for ...
From: Adrian Bunk
Date: Friday, January 19, 2007 - 10:36 am

I had already removed most of the "extern inline"s in the kernel since 
they give warnings with -Wmissing-prototypes (which I'd like to enable 
long-term in the kernel since it helps discovering a class of nasty 
runtime errors).

As far as I can see, all we need is "static inline" with the semantics
"force inlining" for functions in header files and perhaps a handful of 
functions in C files (if any).

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

-

Previous thread: [RFC] [PATCH] Power S3 Resume Optimization Patch. Request for Comment by Seshadri, Harinarayanan on Friday, January 19, 2007 - 1:08 am. (4 messages)

Next thread: Re: [linux-usb-devel] 2.6.20-rc4: usb somehow broken by Prakash Punnoor on Friday, January 19, 2007 - 7:00 am. (1 message)