Skip to content

Commit 0060999

Browse files
authored
Merge pull request #4823 from Mq-b/Inline-functions-vs-macros
Remove the content of the contrast between inline functions and macros
2 parents e8fa241 + f9fee1a commit 0060999

File tree

1 file changed

+47
-68
lines changed

1 file changed

+47
-68
lines changed

docs/cpp/inline-functions-cpp.md

Lines changed: 47 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
---
22
title: "Inline Functions (C++)"
33
description: "The C++ inline keyword can be used to suggest inline functions to the compiler."
4-
ms.date: 08/24/2022
4+
ms.date: 12/07/2023
55
f1_keywords: ["__forceinline_cpp", "__inline_cpp", "inline_cpp", "__inline", "_inline", "__forceinline", "_forceinline"]
66
helpviewer_keywords: ["inline functions [C++], class members"]
7-
ms.assetid: 355f120c-2847-4608-ac04-8dda18ffe10c
87
---
98
# Inline functions (C++)
109

11-
The **`inline`** keyword tells the compiler to substitute the code within the function definition for every instance of a function call.
10+
The **`inline`** keyword suggests that the compiler substitute the code within the function definition in place of each call to that function.
1211

13-
Using inline functions can make your program faster because they eliminate the overhead associated with function calls. The compiler can optimize functions expanded inline in ways that aren't available to normal functions.
12+
In theory, using inline functions can make your program faster because they eliminate the overhead associated with function calls. Calling a function requires pushing the return address on the stack, pushing arguments onto the stack, jumping to the function body, and then executing a return instruction when the function finishes. This process is eliminated by inlining the function. The compiler also has different opportunities to optimize functions expanded inline versus those that aren't. A tradeoff of inline functions is that the overall size of your program can increase.
1413

15-
Inline code substitution occurs at the compiler's discretion. For example, the compiler won't inline a function if its address is taken or if it's too large to inline.
14+
Inline code substitution is done at the compiler's discretion. For example, the compiler won't inline a function if its address is taken or if the compiler decides it's too large.
1615

1716
A function defined in the body of a class declaration is implicitly an inline function.
1817

1918
## Example
2019

21-
In the following class declaration, the `Account` constructor is an inline function. The member functions `GetBalance`, `Deposit`, and `Withdraw` aren't specified as **`inline`** but can be implemented as inline functions.
20+
In the following class declaration, the `Account` constructor is an inline function because it is defined in the body of the class declaration. The member functions `GetBalance`, `Deposit`, and `Withdraw` are specified `inline` in their definitions. The `inline` keyword is optional in the function declarations in the class declaration.
2221

2322
```cpp
2423
// Inline_Member_Functions.cpp
@@ -47,6 +46,7 @@ inline double Account::Withdraw( double Amount )
4746
{
4847
return ( balance -= Amount );
4948
}
49+
5050
int main()
5151
{
5252
}
@@ -55,36 +55,34 @@ int main()
5555
> [!NOTE]
5656
> In the class declaration, the functions were declared without the **`inline`** keyword. The **`inline`** keyword can be specified in the class declaration; the result is the same.
5757
58-
A given inline member function must be declared the same way in every compilation unit. This constraint causes inline functions to behave as if they were instantiated functions. Additionally, there must be exactly one definition of an inline function.
58+
A given inline member function must be declared the same way in every compilation unit. There must be exactly one definition of an inline function.
5959
60-
A class member function defaults to external linkage unless a definition for that function contains the **`inline`** specifier. The preceding example shows that you don't have to declare these functions explicitly with the **`inline`** specifier. Using **`inline`** in the function definition causes it to be an inline function. However, you can't redeclare a function as **`inline`** after a call to that function.
60+
A class member function defaults to external linkage unless a definition for that function contains the **`inline`** specifier. The preceding example shows that you don't have to declare these functions explicitly with the **`inline`** specifier. Using **`inline`** in the function definition suggests to the compiler that it be treated as an inline function. However, you can't redeclare a function as **`inline`** after a call to that function.
6161
6262
## `inline`, `__inline`, and `__forceinline`
6363
64-
The **`inline`** and **`__inline`** specifiers instruct the compiler to insert a copy of the function body into each place the function is called.
64+
The **`inline`** and **`__inline`** specifiers suggest to the compiler that it insert a copy of the function body into each place the function is called.
6565
66-
The insertion, called *inline expansion* or *inlining*, occurs only if the compiler's cost-benefit analysis shows it's worthwhile. Inline expansion minimizes the function-call overhead at the potential cost of larger code size.
66+
The insertion, called *inline expansion* or *inlining*, occurs only if the compiler's own cost-benefit analysis shows it's worthwhile. Inline expansion minimizes the function-call overhead at the potential cost of larger code size.
6767
6868
The **`__forceinline`** keyword overrides the cost-benefit analysis and relies on the judgment of the programmer instead. Exercise caution when using **`__forceinline`**. Indiscriminate use of **`__forceinline`** can result in larger code with only marginal performance gains or, in some cases, even performance losses (because of the increased paging of a larger executable, for example).
6969
7070
The compiler treats the inline expansion options and keywords as suggestions. There's no guarantee that functions will be inlined. You can't force the compiler to inline a particular function, even with the **`__forceinline`** keyword. When you compile with **`/clr`**, the compiler won't inline a function if there are security attributes applied to the function.
7171
7272
For compatibility with previous versions, **`_inline`** and **`_forceinline`** are synonyms for **`__inline`** and **`__forceinline`**, respectively, unless compiler option [`/Za` \(Disable language extensions)](../build/reference/za-ze-disable-language-extensions.md) is specified.
7373
74-
The **`inline`** keyword tells the compiler that inline expansion is preferred. However, the compiler can create a separate instance of the function (instantiate) and create standard calling linkages instead of inserting the code inline. Two cases where this behavior can happen are:
74+
The **`inline`** keyword tells the compiler that inline expansion is preferred. However, the compiler can ignore it. Two cases where this behavior can happen are:
7575
7676
- Recursive functions.
77-
7877
- Functions that are referred to through a pointer elsewhere in the translation unit.
7978
80-
These reasons may interfere with inlining, *as may others*, at the discretion of the compiler; you shouldn't depend on the **`inline`** specifier to cause a function to be inlined.
79+
These reasons may interfere with inlining, *as may others*, as determined by the compiler. Don't depend on the **`inline`** specifier to cause a function to be inlined.
8180
8281
Rather than expand an inline function defined in a header file, the compiler may create it as a callable function in more than one translation unit. The compiler marks the generated function for the linker to prevent one-definition-rule (ODR) violations.
8382
8483
As with normal functions, there's no defined order for argument evaluation in an inline function. In fact, it could be different from the argument evaluation order when passed using the normal function-call protocol.
8584
86-
The [`/Ob`](../build/reference/ob-inline-function-expansion.md) compiler optimization option helps to determine whether inline function expansion actually occurs.
87-
85+
Use the [`/Ob`](../build/reference/ob-inline-function-expansion.md) compiler optimization option to influence whether inline function expansion actually occurs.\
8886
[`/LTCG`](../build/reference/ltcg-link-time-code-generation.md) does cross-module inlining whether it's requested in source code or not.
8987
9088
### Example 1
@@ -121,28 +119,20 @@ private:
121119
122120
The **`__inline`** keyword is equivalent to **`inline`**.
123121
124-
Even with **`__forceinline`**, the compiler can't inline code in all circumstances. The compiler can't inline a function if:
122+
Even with **`__forceinline`**, the compiler can't inline a function if:
125123
126124
- The function or its caller is compiled with **`/Ob0`** (the default option for debug builds).
127-
128125
- The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other).
129-
130126
- The function has a variable argument list.
131-
132127
- The function uses inline assembly, unless compiled with **`/Ox`**, **`/O1`**, or **`/O2`**.
133-
134128
- The function is recursive and doesn't have **`#pragma inline_recursion(on)`** set. With the pragma, recursive functions are inlined to a default depth of 16 calls. To reduce the inlining depth, use [`inline_depth`](../preprocessor/inline-depth.md) pragma.
135-
136129
- The function is virtual and is called virtually. Direct calls to virtual functions can be inlined.
137-
138130
- 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.
139-
140131
- The function is also marked with the [`naked`](../cpp/naked-cpp.md) [`__declspec`](../cpp/declspec.md) modifier.
141132
142133
If the compiler can't inline a function declared with **`__forceinline`**, it generates a level 1 warning, except when:
143134
144135
- The function is compiled by using /Od or /Ob0. No inlining is expected in these cases.
145-
146136
- The function is defined externally, in an included library or another translation unit, or is a virtual call target or indirect call target. The compiler can't identify non-inlined code that it can't find in the current translation unit.
147137
148138
Recursive functions can be replaced with inline code to a depth specified by the [`inline_depth`](../preprocessor/inline-depth.md) pragma, up to a maximum of 16 calls. After that depth, recursive function calls are treated as calls to an instance of the function. The depth to which recursive functions are examined by the inline heuristic can't exceed 16. The [`inline_recursion`](../preprocessor/inline-recursion.md) pragma controls the inline expansion of a function currently under expansion. See the [Inline-Function Expansion](../build/reference/ob-inline-function-expansion.md) (/Ob) compiler option for related information.
@@ -152,12 +142,11 @@ Recursive functions can be replaced with inline code to a depth specified by the
152142
For more information on using the **`inline`** specifier, see:
153143
154144
- [Inline Class Member Functions](../cpp/inline-functions-cpp.md)
155-
156145
- [Defining Inline C++ Functions with dllexport and dllimport](../cpp/defining-inline-cpp-functions-with-dllexport-and-dllimport.md)
157146
158147
## When to use inline functions
159148
160-
Inline functions are best used for small functions such as accessing private data members. The main purpose of these one- or two-line "accessor" functions is to return state information about objects. Short functions are sensitive to the overhead of function calls. Longer functions spend proportionately less time in the calling and returning sequence and benefit less from inlining.
149+
Inline functions are best used for small functions, such as those that provide access to data members. Short functions are sensitive to the overhead of function calls. Longer functions spend proportionately less time in the calling and returning sequence and benefit less from inlining.
161150
162151
A `Point` class can be defined as follows:
163152
@@ -191,72 +180,62 @@ int main()
191180
Assuming coordinate manipulation is a relatively common operation in a client of such a class, specifying the two accessor functions (`x` and `y` in the preceding example) as **`inline`** typically saves the overhead on:
192181

193182
- Function calls (including parameter passing and placing the object's address on the stack)
194-
195183
- Preservation of caller's stack frame
196-
197184
- New stack frame setup
198-
199185
- Return-value communication
200-
201186
- Restoring the old stack frame
202-
203187
- Return
204188

205189
## Inline functions vs. macros
206190

207-
Inline functions are similar to macros, because the function code is expanded at the point of the call at compile time. However, inline functions are parsed by the compiler, and macros are expanded by the preprocessor. As a result, there are several important differences:
191+
A macro has some things in common with an `inline` function. But there are important differences. Consider the following example:
208192

209-
- Inline functions follow all the protocols of type safety enforced on normal functions.
210-
211-
- Inline functions are specified using the same syntax as any other function except that they include the **`inline`** keyword in the function declaration.
212-
213-
- Expressions passed as arguments to inline functions are evaluated once. In some cases, expressions passed as arguments to macros can be evaluated more than once.
193+
```cpp
194+
#include <iostream>
214195

215-
The following example shows a macro that converts lowercase letters to uppercase:
196+
#define mult(a, b) a * b
216197

217-
```cpp
218-
// inline_functions_macro.c
219-
#include <stdio.h>
220-
#include <conio.h>
198+
inline int multiply(int a, int b)
199+
{
200+
return a * b;
201+
}
221202

222-
#define toupper(a) ((a) >= 'a' && ((a) <= 'z') ? ((a)-('a'-'A')):(a))
203+
int main()
204+
{
205+
std::cout << mult(5 + 5, 5 + 5) << std::endl; // outputs 35
206+
std::cout << multiply(5 + 5, 5 + 5) << std::endl; // outputs 100
223207

224-
int main() {
225-
char ch;
226-
printf_s("Enter a character: ");
227-
ch = toupper( getc(stdin) );
228-
printf_s( "%c", ch );
208+
std::cout << mult(2, 2.2) << std::endl>>; // no warning
209+
std::cout << multiply(2, 2.2); // Warning C4244 'argument': conversion from 'double' to 'int', possible loss of data
229210
}
230-
// Sample Input: xyz
231-
// Sample Output: Z
232211
```
233212
234-
The intent of the expression `toupper(getc(stdin))` is that a character should be read from the console device (`stdin`) and, if necessary, converted to uppercase.
213+
```Output
214+
35
215+
100
216+
4.4
217+
4
218+
```
235219

236-
Because of the implementation of the macro, `getc` is executed once to determine whether the character is greater than or equal to `'a'`, and once to determine whether it's less than or equal to `'z'`. If it is in that range, `getc` is executed again to convert the character to uppercase. It means the program waits for two or three characters when, ideally, it should wait for only one
220+
Here are some of the differences between the macro and the inline function:
237221

238-
Inline functions remedy the problem previously described:
222+
- Macros are always expanded inline. However, an inline function is only inlined when the compiler determines it is the optimal thing to do.
223+
- The macro may result in unexpected behavior. For example, the macro `mult(5+5,5+5)` expands to `5 + 5 * 5 + 5` resulting in 35, whereas the function evaluates `10 * 10`. You could address that by defining the macro as #define `mult(a, b) ((a)*(b))`.
224+
- An inline function is subject to semantic processing by the compiler, whereas the preprocessor expands macros without that same benefit. Macros aren't type-safe, whereas functions are.
225+
- Expressions passed as arguments to inline functions are evaluated once. In some cases, expressions passed as arguments to macros can be evaluated more than once. For example, consider the following:
239226

240227
```cpp
241-
// inline_functions_inline.cpp
242-
#include <stdio.h>
243-
#include <conio.h>
244-
245-
inline char toupper( char a ) {
246-
return ((a >= 'a' && a <= 'z') ? a-('a'-'A') : a );
247-
}
228+
#define sqr(a) ((a) * (a))
248229

249-
int main() {
250-
printf_s("Enter a character: ");
251-
char ch = toupper( getc(stdin) );
252-
printf_s( "%c", ch );
230+
int main()
231+
{
232+
int c = 5;
233+
std::cout << sqr(c++) << std::endl; // outputs 25
234+
std::cout << c << std::endl; // outputs 7!
253235
}
254236
```
255237

256-
```Output
257-
Sample Input: a
258-
Sample Output: A
259-
```
238+
In this example, the expression `c++` is evaluated twice; once for each occurrence of `a` in the macro expansion. Instead, if `sqr` were an inline function, the expression `c++` would be evaluated only once.
260239

261240
## See also
262241

0 commit comments

Comments
 (0)