[9] Inline functions, C++ FAQ Lite
[9] Inline functions
(Part of C++ FAQ Lite, Copyright © 1991-98, Marshall Cline, cline@parashift.com)
FAQs in section [9]:
[9.1] What's the deal with inline functions?
[9.2] How can inline functions help with the tradeoff of
safety vs. speed?
[9.3] Why should I use inline functions? Why not just use
plain old #define macros?
[9.4] How do you tell the compiler to make a non-member
function inline?
[9.5] How do you tell the compiler to make a member function
inline?
[9.6] Is there another way to tell the compiler to make a
member function inline?
[9.7] Are inline functions guaranteed to make your performance
better?
[9.1] What's the deal with inline functions?
An inline function is a function whose code gets inserted into the caller's
code stream. Like a #define macro, inline functions improve
performance by avoiding the overhead of the call itself and (especially!) by
the compiler being able to optimize through the call ("procedural
integration").
[ Top | Bottom | Previous section | Next section ]
[9.2] How can inline functions help with the tradeoff of
safety vs. speed?
In straight C, you can achieve "encapsulated structs" by putting a void* in
a struct, in which case the void* points to the real data that is unknown
to users of the struct. Therefore users of the struct don't know how to
interpret the stuff pointed to by the void*, but the access functions cast
the void* to the approprate hidden type. This gives a form of encapsulation.
Unfortunately it forfeits type safety, and also imposes a function call to
access even trivial fields of the struct (if you allowed direct access to the
struct's fields, anyone and everyone would be able to get direct access since
they would of necessity know how to interpret the stuff pointed to by the
void*; this would make it difficult to change the underlying data structure).
Function call overhead is small, but can add up. C++ classes allow function
calls to be expanded inline. This lets you have the safety of encapsulation
along with the speed of direct access. Furthermore the parameter types of
these inline functions are checked by the compiler, an improvement over C's
#define macros.
[ Top | Bottom | Previous section | Next section ]
[9.3] Why should I use inline functions? Why not just use
plain old #define macros?
Because #define macros are evil.
Unlike #define macros, inline functions avoid infamous macro errors
since inline functions always evaluate every argument exactly once.
In other words, invoking an inline function is semantically just like
invoking a regular function, only faster:
// A macro that returns the absolute value of i
#define unsafe(i) \
( (i) >= 0 ? (i) : -(i) )
// An inline function that returns the absolute value of i
inline
int safe(int i)
{
return i >= 0 ? i : -i;
}
int f();
void userCode(int x)
{
int ans;
ans = unsafe(x++); // Error! x is incremented twice
ans = unsafe(f()); // Danger! f() is called twice
ans = safe(x++); // Correct! x is incremented once
ans = safe(f()); // Correct! f() is called once
}
Also unlike macros, argument types are checked, and necessary conversions are
performed correctly.
Macros are bad for your health; don't use them unless you have to.
[ Top | Bottom | Previous section | Next section ]
[9.4] How do you tell the compiler to make a non-member
function inline?
When you declare an inline function, it looks just like a normal function:
void f(int i, char c);
But when you define an inline function, you prepend the function's definition
with the keyword inline, and you put the definition into a header file:
inline
void f(int i, char c)
{
// ...
}
Note: It's imperative that the function's definition (the part between the
{...}) be placed in a header file, unless the function is used only in
a single .cpp file. In particular, if you put the inline function's
definition into a .cpp file and you call it from some other
.cpp file, you'll get an "unresolved external" error from the linker.
[ Top | Bottom | Previous section | Next section ]
[9.5] How do you tell the compiler to make a member function
inline?
When you declare an inline member function, it looks just like a normal
member function:
class Fred {
public:
void f(int i, char c);
};
But when you define an inline member function, you prepend the member
function's definition with the keyword inline, and you put the definition
into a header file:
inline
void Fred::f(int i, char c)
{
// ...
}
It's usually imperative that the function's definition (the part between the
{...}) be placed in a header file. If you put the inline function's
definition into a .cpp file, and if it is called from some other
.cpp file, you'll get an "unresolved external" error from the linker.
[ Top | Bottom | Previous section | Next section ]
[9.6] Is there another way to tell the compiler to make a
member function inline?
Yep: define the member function in the class body itself:
class Fred {
public:
void f(int i, char c)
{
// ...
}
};
Although this is easier on the person who writes the class, it's harder on
all the readers since it mixes "what" a class does with "how" it does them.
Because of this mixture, we normally prefer to define member functions
outside the class body with the inline
keyword. The insight that makes sense of this: in a
reuse-oriented world, there will usually be many people who use your class,
but there is only one person who builds it (yourself); therefore you should do
things that favor the many rather than the few.
[ Top | Bottom | Previous section | Next section ]
[9.7] Are inline functions guaranteed to make your performance
better?
Nope.
Beware that overuse of inline functions can cause code bloat, which can in
turn have a negative performance impact in paging environments.
[ Top | Bottom | Previous section | Next section ]
E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised May 27, 1998
Wyszukiwarka
Podobne podstrony:
function cpdf place inline imagefunction cpdf place inline imagefunction cpdf place inline imagefunction fdf next field namefunction ccvs voidfunction mysql errorfunction mcal event set endfunction mcrypt cbcFunctional Origins of Religious Concepts Ontological and Strategic Selection in Evolved Mindsfunction domnode get contentfunction mcrypt module get algo key sizewięcej podobnych podstron