inline

来源:互联网 发布:mac系统如何用word 编辑:程序博客网 时间:2024/06/02 19:42

source:http://en.wikipedia.org/wiki/Inline_function

Inline function

From Wikipedia, the free encyclopedia
Jump to: navigation, search
This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (October 2009)

In various versions of the C and C++ programming languages, an inline function is a function upon which thecompiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined. Compilers are not obligated to respect this request.

Contents

  • 1Motivation
  • 2Comparison with macros
  • 3Language support
  • 4Analogs in other languages
  • 5Microsoft Visual C++ specific
  • 6Quotes
  • 7See also
  • 8References
  • 9External links

Motivation

Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently. It also has a space benefit for very small functions, and is an enabling transformation for otheroptimizations.

Without inline functions, however, the compiler decides which functions to inline. The programmer has little or no control over which functions are inlined and which are not. Giving this degree of control to the programmer allows for the use of application-specific knowledge in choosing which functions to inline.

Comparison with macros

Traditionally, in languages such as C, inline expansion was accomplished at the source level using parameterized macros. Use of true inline functions, as are available in C99, provides several benefits over this approach:

  • In C, macro invocations do not perform type checking, or even check that arguments are well-formed, whereas function calls usually do.
  • In C, a macro cannot use the return keyword with the same meaning as a function would do (it would make the function that asked the expansion terminate, rather than the macro). In other words, a macro cannot return anything which is not the result of the last expression invoked inside it.
  • Since C macros use mere textual substitution, this may result in unintended side-effects and inefficiency due to re-evaluation of arguments andorder 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. Thus, debugging information for inlined code is usually more helpful than that of macro-expanded code.
  • Many constructs are awkward or impossible to express using macros, or use a significantly different syntax. Inline functions use the same syntax as ordinary functions, and can be inlined and un-inlined at will with ease.

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, andGNU C each have support for inline functions. Different compilers vary in how complex a function they can manage to inline. Mainstream C++ compilers likeMicrosoft Visual C++ and GCC support an option that lets the compilers automatically inline any suitable function, even those not marked as inline functions.

An inline function can be written in C99 or C++ like this:

inline int max(int a, int b){  return (a > b) ? a : b;}

Then, a statement such as the following:

a = max(x, y);

may be transformed into a more direct computation:

a = (x > y) ? x : y;

Analogs in other languages

In the Ada programming language, there exists a pragma for inline functions. Most other languages, including Java and functional languages, do not provide language constructs for inline functions, but often do perform aggressiveinline expansion.

Functions in Common Lisp may be defined as inline as such:[1]

 (declaim (inline dispatch)) (defun dispatch (x)   (funcall     (get (car x) 'dispatch) x))

The Haskell compiler GHC tries to inline functions or values that are small enough but inlining may be noted explicitly using a language pragma:[2]

key_function :: Int -> String -> (Bool, Double){-# INLINE key_function #-}

Microsoft Visual C++ specific

Microsoft Visual C++ and few other compilers support non-standard constructs for defining inline functions, such as __inline and __forceinline specifiers.

  • The __inline keyword is equivalent to inline.
  • The __forceinline keyword allow the programmer to force the compiler to inline the function, but indiscriminate use of __forceinline can result in larger code (bloated executable file), minimal or no performance gain, and in some cases even a loss in performance. The compiler cannot inline the function in all circumstances, even with the __forceinline keyword applied. If the compiler cannot inline a function declared with __forceinline, a warning of level 1 is generated. A list of cases when __forceinline will not take effect is listed below (based on Microsoft Specifications at MSDN):
  1. The function or its caller is compiled with /Ob0 (the default option for debug builds).
  2. The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other).
  3. The function has a variable argument list.
  4. The function uses inline assembly, unless compiled with /Og, /Ox, /O1, or /O2.
  5. The function is recursive and not accompanied by #pragma inline_recursion(on). With the pragma, recursive functions are inlined to a default depth of 16 calls. To reduce the inlining depth, use inline_depth pragma.
  6. The function is virtual and is called virtually. Direct calls to virtual functions can be inlined.
  7. The program takes the address of the function and the call is made via the pointer to the function. Direct calls to functions that have had their address taken can be inlined.
  8. The function is also marked with the naked __declspec modifier.

__forceinline is useful if:

  • inline or __inline is not respected by the compiler (ignored by compiler cost/benefit analyzer)
  • code portability is not required
  • inlining results in a necessary performance boost

Example of portable code:

#ifdef _MSC_VER  #define INLINE __forceinline /* use __forceinline (VC++ specific) */#else  #define INLINE inline        /* use standard inline */#endif INLINE void helloworld() { /* inline function body */ }

Besides the problems associated with inline 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 a particular function should be inlined. Sometimes the compiler may not be able to inline as many functions as the programmer indicates.
  • An important point to note is that the code (of the inline function) gets exposed to its client(the calling function).
  • 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 still requires extra maintenance which typically yields relatively little benefit.
  • Inline functions used in proliferation in native C-based compilation systems can increase compilation time, since the intermediate representation of their bodies is copied into each call site where they are
  • The specification of inline in C99 requires exactly one additional external definition of a function in another compilation unit, when the corresponding inline definition, that can occur multiple times in different compilation units, if that function is used somewhere. That can easily lead to linker errors because such a definition wasn't provided by the programmer. For this reason, inline in C99 often is used together with static, which gives the function internal linkage.
  • In C++, it is necessary to define an inline function in every module (compilation unit) that uses it, whereas an ordinary function must be defined in only a single module. Otherwise it would not be possible to compile a single module independently of all other modules.

For problems with the optimization itself, rather than the language feature, seeproblems with inline expansion.

Quotes

"A function declaration [ . . . ] with an inline specifier declares an inline function. Theinline 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/IEC 14882:2011, 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 anothertranslation 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