You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/cpp/inline-functions-cpp.md
+69-37Lines changed: 69 additions & 37 deletions
Original file line number
Diff line number
Diff line change
@@ -20,35 +20,38 @@ A function defined in the body of a class declaration is implicitly an inline fu
20
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.
@@ -152,13 +155,15 @@ A `Point` class can be defined as follows:
152
155
153
156
```cpp
154
157
// when_to_use_inline_functions.cpp
158
+
// compile with: /c
155
159
classPoint
156
160
{
157
161
public:
158
-
// Define "accessor" functions as
159
-
// reference types.
162
+
// Define "accessor" functions
163
+
// as reference types.
160
164
unsigned& x();
161
165
unsigned& y();
166
+
162
167
private:
163
168
unsigned _x;
164
169
unsigned _y;
@@ -168,13 +173,11 @@ inline unsigned& Point::x()
168
173
{
169
174
return _x;
170
175
}
176
+
171
177
inlineunsigned& Point::y()
172
178
{
173
179
return _y;
174
180
}
175
-
int main()
176
-
{
177
-
}
178
181
```
179
182
180
183
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:
@@ -193,7 +196,9 @@ A macro has some things in common with an `inline` function. But there are impor
193
196
```cpp
194
197
#include<iostream>
195
198
196
-
#definemult(a, b) a * b
199
+
#definemult1(a, b) a * b
200
+
#define mult2(a, b) (a) * (b)
201
+
#define mult3(a, b) ((a) * (b))
197
202
198
203
inlineintmultiply(int a, int b)
199
204
{
@@ -202,40 +207,67 @@ inline int multiply(int a, int b)
std::cout << mult(2, 2.2) << std::endl>>; // no warning
215
+
std::cout << mult3(2, 2.2) << std::endl; // no warning
209
216
std::cout << multiply(2, 2.2); // Warning C4244 'argument': conversion from 'double' to 'int', possible loss of data
210
217
}
211
218
```
212
219
213
220
```Output
214
-
35
215
-
100
221
+
33
222
+
72
223
+
2
224
+
2
216
225
4.4
217
226
4
218
227
```
219
228
220
229
Here are some of the differences between the macro and the inline function:
221
230
222
231
- 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))`.
232
+
- The macro may result in unexpected behavior, which can lead to subtle bugs. For example, the expression `mult1(2 + 2, 3 + 3)` expands to `2 + 2 * 3 + 3` which evaluates to 11, but the expected result is 24. A seemingly valid fix is to add parentheses around both arguments of the function macro, resulting in `#define mult2(a, b) (a) * (b)`, which will solve the issue at hand but can still cause surprising behavior when part of a larger expression. That was demonstrated in the preceding example, and the problem could be addressed by defining the macro as such `#define mult3(a, b) ((a) * (b))`.
224
233
- 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
234
- 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:
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.
263
+
```Output
264
+
30
265
+
7
266
+
25
267
+
6
268
+
```
269
+
270
+
In this example, the function `increment` is called twice as the expression `sqr(increment(c))` expands to `((increment(c)) * (increment(c)))`. This caused the second invocation of `increment` to return 6, hence the expression evaluates to 30. Any expression that contains side effects may affect the result when used in a macro, examine the fully expanded macro to check if the behavior is intended. Instead, if the inline function `square` was used, the function `increment` would only be called once and the correct result of 25 will be obtained.
0 commit comments