about inline functions

F

Falcon Kirtaran

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,
my question is about function inlining.
Suppose I have:

static inline void bar (void)
{
..
}

static inline void foo (void (*f) ())
{
..
f()
..
}

int main (void)
{
..
foo(bar);
..
}

Is it possible for the compiler to inline all together?
What is the standard behavior of c99 in this case?
Thanks,
tano

I'm pretty sure the compiler can, at its option, completely ignore that
you put inline, or inline things you didn't direct it to. Generally I
would let it take care of that kind of thing itself.

- --
- --Falcon Darkstar Christopher Momot
- --
- --OpenPGP: (7902:4457) 9282:A431

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJ85E3AAoJEKmxP9YxEE4rAwoQALb4xZqR4o6P/K8RguMydn5O
N1clRhnErP68gpuOkpUB2Fl75etar4nh7sbXt/pfIDxoq7U5sBCZg5Iriv3x++Gq
PxhZ5ouH+Yb87utX/q6QovyJwuMgeI7W47HTiaiTyihyEZACNDydgpX1x3srIWt3
1x+3rwgqHdNgADEfgP3bhAzvTT6wGS2jYaStRpzQuEZ4r6v3/2Blc0NMxUnCjfWo
ZPOOLYMw+aTFkGQcMGnDBHArsNbP9gV3CEa/8XhFVcOyQO7O4Qa2ZWAflLZcwryl
o1bGlK5MXPhGkYSwe0D2113tj05yNB4HIXU1wECPB1tYY6ldxujr104A7BP4oWyl
KPiHWGAXloqXrdo4GHh4Y+L3eLwd89n4gg2F87T2OPg2s9Q8zVEzWfNxEu1SphSQ
em5LM9rZ3z1wrVvnqaeDo19ajsW2JZC1EKgydXdnxjT08JdcHCoCQs4pH6PasFQU
W/Hl5ZYLmaEGZhFZcJIU8t6OlQbj1/zoyUqt/AO7h8CYfvIQ+rfC43hn3ukz1RQw
Ak+6BNYQisoihYKPK8WnVTly8TOK201M39WZtAw/9pqKMSZoWkt9nXLoTAeR99EA
z2COCXosZw8cdb9lc0SHYoWlOu/UyHq73PkAgC9pHzADH+CMaN/Sm4Jn9hlHuo9g
qakRsPFUnoRwCRsdF+eC
=11Q4
-----END PGP SIGNATURE-----
 
?

\\

Hello,
my question is about function inlining.
Suppose I have:

static inline void bar (void)
{
..
}

static inline void foo (void (*f) ())
{
..
f()
..
}

int main (void)
{
..
foo(bar);
..
}

Is it possible for the compiler to inline all together?
What is the standard behavior of c99 in this case?
Thanks,
tano
 
?

\\

inline is, like register, a hint to the compiler. It was obsolete almost as
soon as it was introduced, because it is not normally difficult for an
optimising compiler to make this decision.

Trying to compile on gcc with the -Winline option does not give me
any warning message, so I think in theory it can do. But in practice,
even turning on -O3 optimization looking at assembly code I do not get
bar() inline.
 
S

s0suk3

inline is, like register, a hint to the compiler. It was obsolete almost as
soon as it was introduced, because it is not normally difficult for an
optimising compiler to make this decision.

But inline avoids a problem when you want to have a header file that
contains an inline function, and that header is included in more than
one file.

As I understand it, a file may contain the definition of an inline
function, even if another function with the same name and with
external linkage already exists.

For example:

// my_header.h

#ifndef MY_HEADER_H_
#define MY_HEADER_H_

// Helper function that's used in file1.c and file2.c
inline void f(void)
{
// do something...
}

void g(void); // defined in file1.c
void h(void); // defined in file2.c

#endif // MY_HEADER_H_

// file1.c

#include "my_header.h"

void g(void)
{
// do something...
}

// file2.c

#include "my_header.h"

void h(void)
{
// do something...
}

// main.c

#include "my_header.h"

int main(void)
{
g();
h();
return 0;
}

file1.c, file2.c and main.c will each end up with their own definition
of f(), but that's OK because those definitions are inline. If you
omitted the inline declaration specifier in the definition of f(), you
would get a link error because of multiple external definitions.

Sebastian
 
C

CBFalconer

Christian said:
But you can achieve roughly the same effect by declaring the function static.

'static' for a function has nothing to do with inline. It simply
means that the functions is not accessible from outside the source
file in which it is declared, except when specifically passed out
as a pointer to a function.
 
J

James Kuyper

CBFalconer said:
'static' for a function has nothing to do with inline. It simply
means that the functions is not accessible from outside the source
file in which it is declared, except when specifically passed out
as a pointer to a function.

Yes and no. 'inline' is just a hint to the compiler. The point is, a
static function provides very nearly the same hint.

A static function, often doesn't have to be an actual function - it
could be in-lined at each call, and a good optimizing compiler will do
just that, taking advantage of the as-if rule. Some features of the code
can prevent inlining it, such as taking a pointer to the function,
especially if that pointer is passed to code in some other translation
unit. However, if you have a function for which 'inline' is a good idea,
it's often the case that simply declaring it 'static' without the
'inline' keyword is sufficient to allow the compiler to perform this
optimization.

It was for this reason that many people opposed the creation of the
'inline' keyword. Using 'static' doesn't guarantee that the function
will be inlined, even if there's no good reason not to - but the same
can be said of the 'inline' keyword.
 
C

Chetan

James Kuyper said:
Yes and no. 'inline' is just a hint to the compiler. The point is, a static
function provides very nearly the same hint.

A static function, often doesn't have to be an actual function - it could be
in-lined at each call, and a good optimizing compiler will do just that, taking
advantage of the as-if rule. Some features of the code can prevent inlining it,
such as taking a pointer to the function, especially if that pointer is passed
to code in some other translation unit. However, if you have a function for
which 'inline' is a good idea, it's often the case that simply declaring it
static' without the 'inline' keyword is sufficient to allow the compiler to
perform this optimization.

It was for this reason that many people opposed the creation of the 'inline'
keyword. Using 'static' doesn't guarantee that the function will be inlined,
even if there's no good reason not to - but the same can be said of the
inline' keyword.

Inline and static serve different purposes. For example, a function
that has inline keyword and is in a shared header file can give
multiple definitions warning if it isn't inlined and is not created as
a common symbol. A static declaration guarantees that such errors will
not happen, but then there might be multiple copies of the code.
 
K

Kenny McCormack

Han from China said:
Using the same "as if" argument, we could turn this newsgroup into a
nebulous mass of confusion where nothing anyone says is right enough.

Nah... That could never happen. That would be just, too, too, extreme,
wouldn't it?
 
J

James Kuyper

Chetan said:
Inline and static serve different purposes.

Even without either keyword, the as-if rule often allows calls to
functions defined in the same translation unit to be inlined; but an
actual external definition for the function must also be generated,
because there might be an extern declaration for it in some other
translation unit.

Despite serving different purposes, what both static and inline allow
(and what neither keyword guarantees) is the removal of the external
definition, leaving only the inlined code.

The key difference between them is that an inline function does not
qualify as an external definition, making it an error to do such things
as passing a pointer to that function to code in a different translation
unit. For a static function, passing such a pointer merely prevents
removal of the the external definition.
... For example, a function
that has inline keyword and is in a shared header file can give
multiple definitions warning if it isn't inlined and is not created as
a common symbol. A static declaration guarantees that such errors will
not happen, but then there might be multiple copies of the code.

Yes, but the same can be said about inline: "An inline definition does
not provide an external definition for the function, and does not forbid
an external definition in another translation unit." (6.7.4p6)
 
C

CBFalconer

James said:
Yes and no. 'inline' is just a hint to the compiler. The point is, a
static function provides very nearly the same hint.
.... snip ...

It was for this reason that many people opposed the creation of the
'inline' keyword. Using 'static' doesn't guarantee that the function
will be inlined, even if there's no good reason not to - but the same
can be said of the 'inline' keyword.

However static DOES guarantee that that function name is not
visible outside of its source file.
 
J

jameskuyper

CBFalconer said:
James Kuyper wrote: ....

However static DOES guarantee that that function name is not
visible outside of its source file.

More accurately, it guarantees that the function's name can be visible
in other translation units, but if so, that name will not refer to
that function, but to something else (which might, among other
possibilities, be a different function of the same name, identically
defined, in the other translation unit).

That doesn't conflict with anything I said. It does mean that if you
need a function that is both inlined and available as an external
definition, static is not the way to go, at least when creating the
external definition (you can use static in other translation units, if
there's no need for those other translation units to have access to
the external definition).
 
C

Chetan

James Kuyper said:
Even without either keyword, the as-if rule often allows calls to functions
defined in the same translation unit to be inlined; but an actual external
definition for the function must also be generated, because there might be an
extern declaration for it in some other translation unit.

Despite serving different purposes, what both static and inline allow (and what
neither keyword guarantees) is the removal of the external definition, leaving
only the inlined code.

The key difference between them is that an inline function does not qualify as
an external definition, making it an error to do such things as passing a
pointer to that function to code in a different translation unit. For a static
function, passing such a pointer merely prevents removal of the the external
definition.


Yes, but the same can be said about inline: "An inline definition does not
provide an external definition for the function, and does not forbid an
external definition in another translation unit." (6.7.4p6)

There may be a difference between what is allowed and what may
actually be implemented (out of what is allowed). A compiler may provide
options to control how inlining is handled, for example. Thus the
point here is that static should be seen as a keyword indicating scope
and inline as a hint to the compiler to try to inline the function.
It is quite possible for a compiler to operate in a mode where
functions are not inlined unless explicitly instructed to do so, but
that option does not exist with static regarding scope.
 
J

James Kuyper

Chetan wrote:
....
There may be a difference between what is allowed and what may
actually be implemented (out of what is allowed).

That is what is called "quality of implementation"; and given the fact
that 'inline' is no more than a hint to the compiler, 'inline' doesn't
necessarily have any effect on what may actually be implemented.
... A compiler may provide
options to control how inlining is handled, for example. Thus the
point here is that static should be seen as a keyword indicating scope
and inline as a hint to the compiler to try to inline the function.
It is quite possible for a compiler to operate in a mode where
functions are not inlined unless explicitly instructed to do so, but
that option does not exist with static regarding scope.

The point is that a compiler can completely ignore 'inline', except for
the purpose of diagnosing syntax errors and constraint violations. A
compiler like the one you describe can even refuse to inline functions
explicitly declared inline; a more aggressive compiler could inline
every function call that can be inlined without changing it's behavior,
regardless of whether or not it is declared inline.

My point is that the static keyword has a big effect on which functions
can be inlined w/o changing their behavior. The 'inline' keyword is only
a suggestion; one that is ignored by many compilers whose designers
assume that the compiler usually knows better than the developer what
function calls should be inlined - and for many of those compilers, that
assumption is nothing more or less than the literal truth.
 
C

Chetan

James Kuyper said:
Chetan wrote:
...

That is what is called "quality of implementation"; and given the fact that
inline' is no more than a hint to the compiler, 'inline' doesn't necessarily
have any effect on what may actually be implemented.

It may be quality of implementation, but there is no reason to
make high quality a requirement if one can help it.
The point is that a compiler can completely ignore 'inline', except for the
purpose of diagnosing syntax errors and constraint violations. A compiler like
the one you describe can even refuse to inline functions explicitly declared
inline; a more aggressive compiler could inline every function call that can be
inlined without changing it's behavior, regardless of whether or not it is
declared inline.

My point is that the static keyword has a big effect on which functions can be
inlined w/o changing their behavior. The 'inline' keyword is only a suggestion;
one that is ignored by many compilers whose designers assume that the compiler
usually knows better than the developer what function calls should be inlined -
and for many of those compilers, that assumption is nothing more or less than
the literal truth.

The situation with regard to inline is very similar to register
variable declaration. It is a hint that allowed compiler to optimize
access to such variables. An automatic variable is like a static
function in that context. Nowadays variables are not usually declared
as register because compilers have improved a lot. However, in
writing code that may work on unknown compilers, it helps to mark
variables that _have_ to be in registers. It has a better chance of
being allocated a register. The same goes for inline.

Practically speaking, declare such functions as both inline and
static, especially when included in multiple translation unit.
 
D

Dik T. Winter

>
> However static DOES guarantee that that function name is not
> visible outside of its source file.

However the remark about near equivalence of "inline" and "static" was about
"inline" with a function defined in a header file:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top