Previous Page
Next Page

7.5. Inline Functions

Ordinarily, calling a function causes the computer to save its current instruction address, jump to the function called and execute it, then make the return jump to the saved address. With small functions that you need to call often, this can degrade the program's run-time behavior substantially. As a result, C99 has introduced the option of defining inline functions. The keyword inline is a request to the compiler to insert the function's machine code wherever the function is called in the program. The result is that the function is executed as efficiently as if you had inserted the statements from the function body in place of the function call in the source code.

To define a function as an inline function, use the function specifier inline in its definition. In Example 7-7, swapf( ) is defined as an inline function that exchanges the values of two float variables, and the function selection_sortf( ) calls the inline function swapf( ).

Example 7-7. Function swapf( )
// The function swapf( ) exchanges the values of two float variables.
// Arguments:    Two pointers to float.
// Return value: None.

inline void swapf( float *p1, float *p2 ) // Define it as an inline function.
{
   float tmp = *p1; *p1 = *p2; p2 = tmp;
}

// The function selection_sortf( ) uses the selection-sort
// algorithm to sort an array of float elements.
// Arguments:    An array of float, and its length.
// Return value: None.

void selection_sortf( float a[ ], int n )  // Sort an array a of length n.
{
  register int i, j, mini;                // Three index variables.
  for ( i = 0;  i < n - 1;  ++i )
  {
    mini = i;                 // Search for the minimum starting at index i.
    for ( j = i+1;  j < n;  ++j )
      if ( a[j] < a[mini] )
        mini = j;
      swapf( a+i, a+mini ); // Swap the minimum with the element at index i.
   }
}

It is generally not a good idea to define a function containing loops, such as selection_sortf( ), as inline . Example 7-7 uses inline instead to speed up the instructions inside a for loop.

The inline specifier is not imperative: the compiler may ignore it. Recursive functions, for example, are usually not compiled inline. It is up to the given compiler to determine when a function defined with inline is actually inserted inline.

Unlike other functions, you must repeat the definitions of inline functions in each translation unit in which you use them. The compiler must have the function definition at hand in order to insert the inline code. For this reason, function definitions with inline are customarily written in header files.

If all the declarations of a function in a given translation unit have the inline specifier, but not the extern specifier, then the function has an inline definition . An inline definition is specific to the translation unit; it does not constitute an external definition, and therefore another translation unit may contain an external definition of the function. If there is an external definition in addition to the inline definition, then the compiler is free to choose which of the two function definitions to use.

If you use the storage class specifier extern outside all other functions in a declaration of a function that has been defined with inline, then the function's definition is external. For example, the following declaration, if placed in the same translation unit with the definition of swapf( ) in Example 7-7, would produce an external definition:

extern void swapf( float *p1, float *p2 );

Once the function swapf( ) has an external definition, other translation units only need to contain an ordinary declaration of the function in order to call it. However, calls to the function from other translation units will not be compiled inline.

Inline functions are ordinary functions, except for the way they are called in machine code. Like ordinary functions, an inline function has a unique address. If macros are used in the statements of an inline function, the preprocessor expands them with their values as defined at the point where the function definition occurs in the source code. However, you should not define modifiable objects with static storage duration in an inline function that is not likewise declared as static.


Previous Page
Next Page