Inline function
|
In computer science, an inline function is a programming language construct used to suggest to a compiler that a particular function be subjected to in-line expansion; that is, it suggests that the compiler insert the complete body of the function in every context where that function is used.
Contents |
Motivation
Inline expansion is typically used to eliminate the inherent time overhead that occurs in calling a function; it is typically used for functions that execute very quickly, as this overhead is more significant in this case. It also has a space benefit for very small functions, and is an enabling transformation for other optimizations.
Without inline functions, however, the programmer has little to no control over which functions are inlined and which are not; the compiler alone makes this decision. Adding this degree of control allows application-specific knowledge, such as frequently executed functions, to be exploited in choosing which functions to inline.
Also, in some languages inline functions interact intimately with the compilation model; for example, in C++, it is necessary to define an inline function in every module that uses it, whereas ordinary functions must be defined in only a single module. This facilitates compilation of modules independently of all other modules.
Comparison to macros
Traditionally, in languages such as C, inline expansion was accomplished at the source level using parameterized macros. Inlining provides several benefits over this approach:
- Macro invocations do not perform type checking, or even check that arguments are well-formed, whereas function calls usually do.
- Since C macros use mere textual substitution, this may result in unintended side-effects and inefficiency due to re-evaluation of arguments and order of operations.
- Compiler errors within macros are often difficult to understand, because they refer to the expanded code, rather than the code the programmer typed.
- Many constructs are awkward or impossible to express using macros, or use a significantly different syntax. In-line functions use the same syntax as ordinary functions, and can be inlined and un-inlined at will with ease.
- Debugging information for inlined code is usually more helpful than that of macro-expanded code.
Many compilers can also inline expand some recursive functions; recursive macros are typically illegal.
Bjarne Stroustrup, the designer of C++, likes to emphasize that macros should be avoided wherever possible, and advocates extensive use of inline functions.
Language support
C++, C99, and GNU C each have support for inline functions, although 1990 ANSI C, the dialect of C most commonly used in practice, does not. In the Ada programming language, a pragma can be used to inline functions. Most other languages, including Java and functional languages, do not provide inline functions, but often do perform inline expansion aggressively. Different compilers vary in how complex a function they can manage to in-line. Mainstream C++ compilers like Microsoft Visual C++ and GCC support an option that lets the compilers automatically inline any suitable function, even those are not marked as inline functions.
An in-line function can be written in C++ like this:
inline int max (int a, int b) { if (a > b) return a; else return b; }
a = max (x, y); // This is now equivalent to "a = (x > y ? x : y);"
Problems with inline functions
Besides the problems associated with in-line expansion in general, inline functions as a language feature may not be as valuable as they appear, for a number of reasons:
- Often, a compiler is in a better position than a human to decide whether or not a particular function should be inlined; in particular, the compiler may not be willing or able to inline many functions that the human asks it to.
- As functions evolve, they may become suitable for inlining where they were not before, or no longer suitable for inlining where they were before. While inlining or un-inlining a function is easier than converting to and from macros, it's still added maintenance effort which in most cases has relatively little benefit.
- Inline functions used in proliferation in naive C-based compilation systems can increase compilation time, since their bodies are included textually in every source file in which they are used.
For problems with the optimization itself, rather than the language feature, see problems with inline expansion.
Quotes
- "A function declaration [ . . . ] with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected."
- — ISO 14882:1998(E), the current C++ standard, section 7.1.2
- "A function declared with an inline function specifier is an inline function. [ . . . ] Making a function an inline function suggests that calls to the function be as fast as possible. The extent to which such suggestions are effective is implementation-defined (footnote: For example, an implementation might never perform inline substitution, or might only perform inline substitutions to calls in the scope of an inline declaration.)
- "[ . . . ] An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition."
- — ISO 9899:1999(E), the C99 standard, section 6.7.4