Introduction
C++ added the inline keyword that can prefix a function definition, such as:
inline int max_int( int a, int b ) { return a > b ? a : b; }
to give the compiler a “hint” that the program overall might benefit in performance from the function being inlined.
A function that has been inlined has had its code expanded at every point it’s been called rather than performing the normal function-call mechanism of:
- Saving registers.
- Pushing argument values onto the stack.
- Executing the call instruction.
- The function eventually executing the ret instruction.
- Restoring registers.
For very small functions, inlining can yield a performance gain. But like most everything else, there are trade-offs.
The inline keyword was back-ported to C99, but with slightly different requirements — more later.
Differences from Macros
Inline functions are like (and meant to replace many uses of) function-like macros. Generally, this is a good thing because inline functions are functions and have full function semantics rather than mere text substitution done by the preprocessor that doesn’t understand either C or C++.
A naively equivalent macro to the max_int() function:
#define MAX_INT(A,B) A > B ? A : B /* bad implementation */
has the following problems:
- Expanded arguments, e.g., MAX(n & 0xFF, 8), can result in the wrong operator precedence.
- Arguments having side effects, e.g., MAX(n++, 8), can have multiple side effects.
- There’s no type-checking of the arguments at definition.
- Errors are often verbose and hard to read.
Additionally, a macro:
- Can modify its argument (that often is not what you want).
Inline functions have none of these problems yet can yield the same performance benefit. Hence, use inline functions instead of function-like macros.
Only a Hint
As mentioned, specifying inline is only a “hint” to the compiler that the program overall might benefit in performance from the function being inlined. The compiler is free to ignore the hint.
Why? Because there are cases when it’s either not a good idea or impossible. A function is either not inlined or typically not inlined when any one of the following is true:
- The function is “too big.”
- You call the function via a pointer-to-function.
- The function is recursive.
- The function has a loop.
There may be other reasons. It’s all highly dependent on the function, its arguments, the compiler, and whatever options are given to it.
If the compiler either can’t or chooses not to inline a function, it does not warn you that it hasn’t done so (by default). Some compilers, e.g., gcc, have a -Winline option that will warn you and give you the reason why a function wasn’t inlined.
Specifying inline is similar to older code specifying register — they’re both only hints.
When (and When Not) to Inline
For most functions, the bulk of the cost of executing the function is in the function’s body, not in the function-call mechanism. Hence, in order for a function to be a good candidate for inlining, it generally has to be:
- Small enough so that the cost of the function-call mechanism dominates.
- Used in places where performance actually matters, e.g., in tight loops.
When in doubt, profile your code. Using inline is not a magic “make me faster” keyword. Additionally, over-use of inline can lead to code bloat that additionally make the performance of your program worse overall.
For more, see The inline disease.
Functions that are often good candidates for inlining include:
- “One-liners” such as “getters” and “setters.”
- Simple wrappers around calls to other functions that supply specific values for arguments or do casts.
An ideal inline function both increases performance and decreases code size.
However, one caveat for any inline function is that if its definition changes, it will require recompiling all code that uses it.
Inline Optimizations
If an inline function is actually inlined by the compiler, then, in addition to eliding the code for the normal function-call mechanism, the compiler may also be able to:
- Eliminate one or more function arguments completely whose values are constants via immediate addressing.
- Perform better optimizations spanning the code the function is inlined into that it normally couldn’t perform across function boundaries.
Inline Function Definition
In order for the compiler to be able to inline a function, it has to be able to “see” its definition (not just its declaration) in every .c or .cpp file it’s used in just like a macro. Hence, an inline function must be defined in a header file.
Normally, a function, like everything else, must have exactly one definition by adhering to the one definition rule (ODR). However, since the definition of an inline function is “seen” in multiple .c or .cpp files, the ODR is suspended for that function.
It is possible to have different definitions for inline functions having the same name, but this results in undefined behavior since the compiler has no way to check that every definition is the same.
To inline a function in C++, all you need do is prefix the function definition with inline — that’s it. The compiler and/or linker will automatically discard all but one definition from the final executable file for you.
However, to inline a function in C, you additionally must explicitly tell the compiler into what .o file to put the one definition in the event the compiler is either unable or unwilling to inline a function via extern inline.
For example, in exactly one .c file, you would declare a function like:
// util.c extern inline int max_int( int, int );
That tells the compiler to “put the one definition for max_int() into util.o.”
Alternatively in C, you can instead declare an inline function static also:
static inline int max_int( int a, int b ) { return a > b ? a : b; }
If you do this, then:
- You do not have to declare a function extern inline anywhere.
- However, if the compiler doesn’t inline a function, it will generate a definition in every .c file it’s included into again leading to code bloat.
- If the function has any static local variables, every definition will have distinct copies (that may or may not be what you want).
Conclusion
Inline functions, if used judiciously, can yield performance gains. Generally, only very small functions are good candidates for inlining.
Starting in C++11, inline functions can alternatively be declared constexpr, but that’s a story for another time.
References
- Linux kernel coding style, §15 The inline disease.
- Myth and reality about inline in C99.
- The Annotated C++ Reference Manual, Margaret A. Ellis & Bjarne Stroustrup, Addison-Wesley, 1990, ISBN 0-201-51459-1, §7.1.2 Function Specifiers, pp. 99–105.
The above is the detailed content of Inline Functions in C and C++. For more information, please follow other related articles on the PHP Chinese website!

There are four commonly used XML libraries in C: TinyXML-2, PugiXML, Xerces-C, and RapidXML. 1.TinyXML-2 is suitable for environments with limited resources, lightweight but limited functions. 2. PugiXML is fast and supports XPath query, suitable for complex XML structures. 3.Xerces-C is powerful, supports DOM and SAX resolution, and is suitable for complex processing. 4. RapidXML focuses on performance and parses extremely fast, but does not support XPath queries.

C interacts with XML through third-party libraries (such as TinyXML, Pugixml, Xerces-C). 1) Use the library to parse XML files and convert them into C-processable data structures. 2) When generating XML, convert the C data structure to XML format. 3) In practical applications, XML is often used for configuration files and data exchange to improve development efficiency.

The main differences between C# and C are syntax, performance and application scenarios. 1) The C# syntax is more concise, supports garbage collection, and is suitable for .NET framework development. 2) C has higher performance and requires manual memory management, which is often used in system programming and game development.

The history and evolution of C# and C are unique, and the future prospects are also different. 1.C was invented by BjarneStroustrup in 1983 to introduce object-oriented programming into the C language. Its evolution process includes multiple standardizations, such as C 11 introducing auto keywords and lambda expressions, C 20 introducing concepts and coroutines, and will focus on performance and system-level programming in the future. 2.C# was released by Microsoft in 2000. Combining the advantages of C and Java, its evolution focuses on simplicity and productivity. For example, C#2.0 introduced generics and C#5.0 introduced asynchronous programming, which will focus on developers' productivity and cloud computing in the future.

There are significant differences in the learning curves of C# and C and developer experience. 1) The learning curve of C# is relatively flat and is suitable for rapid development and enterprise-level applications. 2) The learning curve of C is steep and is suitable for high-performance and low-level control scenarios.

There are significant differences in how C# and C implement and features in object-oriented programming (OOP). 1) The class definition and syntax of C# are more concise and support advanced features such as LINQ. 2) C provides finer granular control, suitable for system programming and high performance needs. Both have their own advantages, and the choice should be based on the specific application scenario.

Converting from XML to C and performing data operations can be achieved through the following steps: 1) parsing XML files using tinyxml2 library, 2) mapping data into C's data structure, 3) using C standard library such as std::vector for data operations. Through these steps, data converted from XML can be processed and manipulated efficiently.

C# uses automatic garbage collection mechanism, while C uses manual memory management. 1. C#'s garbage collector automatically manages memory to reduce the risk of memory leakage, but may lead to performance degradation. 2.C provides flexible memory control, suitable for applications that require fine management, but should be handled with caution to avoid memory leakage.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Mac version
God-level code editing software (SublimeText3)

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Atom editor mac version download
The most popular open source editor