Skip to content

Commit 9327997

Browse files
committed
Updating to C++23
1 parent fbd138c commit 9327997

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

04-functions.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ int main() {
9090
}
9191
```
9292

93-
In fact, the call of `abs_value()` yielding its return value could be used directly in the second `cout` call, which means a named variable `a` is not needed. Using a (temporary) variable to store the return value of a function could be seen as unnecessary if the value is used only once, however if the return value of a function is needed more than once and is not stored in a variable, the function must be called multiple times which could become inefficient.
93+
In fact, the call of `abs_value()` yielding its return value could be used directly in the second `cout` call, which means a named variable `a` is not needed. Using a (temporary) variable to store the return value of a function could be seen as unnecessary if the value is used only once, however if the return value of a function is needed more than once and is not stored in a variable, the function must be called every time its return value is needed, which could become inefficient.
9494

9595
**Experiment**
9696

9797
* Modify `main()` so that the variable `a` is not needed.
9898

9999
* Modify `abs_value()` so that the keyword `else` is used. Does this make the code any more obvious in intent? Do you get a warning about there being no `return` keyword outside of the `if`-`else` clauses? What happens if you add a third `return` statement just before the function's closing brace?
100100

101-
* Rearrange the order of the definitions (all beginnning with `int`). What errors do you get?
101+
* Rearrange the order of the variable and/or function definitions (all beginning with `int`). What errors do you get?
102102

103103
## Parameters by value
104104

@@ -333,7 +333,7 @@ f(): int: 1
333333
f(): double: 2.5
334334
```
335335
336-
The function to be used is determined at compile-time from the usage at the call site, as the types of the arguments are always known. A best-match is performed in the case of no exact match, so for example `f('a')` would call `f(int)` while `f(0.5f)` would call `f(double)`.
336+
The function to be used is determined at compile-time from the usage at the call site, as the types of the arguments are always known. A best-match is performed in the case of no exact match, so for example `f('a')` would call `f(int i)` while `f(0.5f)` would call `f(double d)`.
337337
338338
**Experiment**
339339
@@ -346,12 +346,12 @@ Variables declared `static` inside a function body are in fact global variables
346346
```cpp
347347
// 04-static-var.cpp : preserving function state in a static variable
348348
349-
#include <iostream>
349+
#include <print>
350350
using namespace std;
351351
352352
void f() {
353353
static int s{1};
354-
cout << s << '\n';
354+
println("{}", s);
355355
++s;
356356
}
357357
@@ -425,12 +425,12 @@ There are three main new things to notice about this program.
425425

426426
## Inline functions
427427

428-
Functions can be declared as inline functions by using the keyword `inline` before the return type in the function definition. The main aim of declaring a function `inline` is to remove the time overhead of a function call; the code is replicated for each function call *in place* at the call site(s). Functions declared with `inline` must be present (and identical) in each translation unit that uses them, hence they often appear in header files; this is a special relaxation of the ODR. Overuse of inline functions can lead to *code-bloat*, so they are best reserved for very short functions. The following program demonstrates use of the `inline` keyword:
428+
Functions can be declared as inline functions by using the keyword `inline` before the return type in the function definition. The main aim of declaring a function `inline` is to remove the time overhead of a function call; the function body code is replicated for each function call *in place* at the call site(s). Functions declared with `inline` must be present (and identical) in each translation unit that uses them, hence they often appear in header files; this is a special relaxation of the ODR. Overuse of inline functions can lead to *code-bloat*, so they are best reserved for very short functions. The following program demonstrates use of the `inline` keyword:
429429

430430
```cpp
431431
// 04-inline.cpp : use of an inline function
432432

433-
#include <iostream>
433+
#include <print>
434434
using namespace std;
435435

436436
inline void swap(int& x, int& y) {
@@ -441,9 +441,9 @@ inline void swap(int& x, int& y) {
441441

442442
int main() {
443443
int a = 1, b = 2;
444-
cout << "(1) a = " << a << ", b = " << b << '\n';
444+
println("(1) a = {}, b = {}", a, b);
445445
swap(a, b);
446-
cout << "(2) a = " << a << ", b = " << b << '\n';
446+
println("(2) a = {}, b = {}", a, b);
447447
}
448448
```
449449
@@ -504,7 +504,7 @@ Note that it is **not** necessary (or even possible) to use `if constexpr` for t
504504

505505
## Non-returning and noexcept functions
506506

507-
It is possible to write a function which never returns, for example using an infinite loop. Another example might be a function that causes an abnormal early exit from the running program; the Modern C++ way of doing this is to throw an exception, or even call `std::terminate()` directly (the C Standard Library also provides `abort()`, `exit()` and `quick_exit()` but these do not deallocate all global objects correctly). The way to indicate this property to the compiler is to use the `[[noreturn]]` attribute when declaring the function, as shown in this example program:
507+
It is possible to write a function which never returns, for example using an infinite loop. Another example might be a function that causes an abnormal early exit from the running program; the Modern C++ way of doing this is to throw an exception, or even to call `std::terminate()` directly (the C Standard Library also provides `abort()`, `exit()` and `quick_exit()` but these do not deallocate all global objects correctly). The way to indicate this property to the compiler is to use the `[[noreturn]]` attribute when declaring the function, as shown in this example program:
508508

509509
```cpp
510510
// 04-noreturn.cpp : program which does not return from main()
@@ -534,15 +534,15 @@ The keyword `noexcept` is used to declare that a function is guaranteed to not t
534534
```cpp
535535
// 04-noexcept.cpp : a noexcept function throwing an exception
536536
537-
#include <iostream>
537+
#include <print>
538538
#include <stdexcept>
539539
using namespace std;
540540
541541
int throw_if_zero(int i) noexcept {
542542
if (!i) {
543543
throw runtime_error("found a zero");
544544
}
545-
cout << "throw_if_zero(): " << i << '\n';
545+
println("throw_if_zero(): {}", i);
546546
}
547547
548548
int main() {
@@ -552,14 +552,14 @@ int main() {
552552
throw_if_zero(0);
553553
}
554554
catch(...) {
555-
cout << "Caught an exception!\n";
555+
println("Caught an exception!");
556556
}
557-
cout << "Leaving main()\n";
557+
println("Leaving main()\n");
558558
}
559559
```
560560

561561
**Experiment:**
562562

563563
* Remove the `noexcept` keyword. Does the program compile? What is the output when run?
564564

565-
*All text and program code &copy;2019-2022 Richard Spencer, all rights reserved.*
565+
*All text and program code &copy;2019-2024 Richard Spencer, all rights reserved.*

0 commit comments

Comments
 (0)