# C++20 C++ is a versatile language with sharp edges as well as pragmatic compromises. It is truly multi-paradigm: *procedural*, *object-oriented*, *functional*, and *generic*. At a low level, it is *stricter C* with richer compile time information. At a high level, it is the interaction of *iterators*, *allocators*, and *executors* (scheduled for C\++23). :::spoiler #### Paradigms and corresponding core language features - Procedural: conditionals and loop. - Object-oriented: class. - Functional: lambda. - Generic: template and concept. #### Compared to C besides programming paradigms - Stricter rules: C++ has stricter alignment and type checks. This tends to eliminate obvious error in these aspects. - Type-safe `enum` and `union` in the name of `enum class` and `variant`, respectively. - Richer compile time information (C is not inherently deficient in this aspect; it seems more of a choice for C to no do so): this allows for - more aggressive optimizations, - automatic type deductions, and - function and operator overloading. - C++ support user-defined namespaces, even inline namespaces. C only has 4 pre-defined namespaces: label, tag, member, and other. - C++ is about to get a new build model -- modules. [This](https://vector-of-bool.github.io/2019/10/07/modules-3.html) is a short and good read. - The C++ standard library contains a lot of useful data structures and algorithms, but a common implementation of its default allocator was **once** plagued with [unexpected problems](https://www.zerotier.com/2017/05/05/the-horror-in-the-standard-library/). - Many others. #### Compared to C regarding programming paradigms - OO can definitely be achieved with C, but one might as well just use C++. - Encapsulation: forward declare a struct in a header file along with its member functions defined as ordinary functions that take the pointer to the struct as first argument. Define the struct in another source file consists of member data. - Inheritence/polymorphism: a derived struct is an ordinary struct whose first member data is an object of the base struct. Then, pointer casting magic will do the job. See [this](http://www.deleveld.dds.nl/inherit.htm). - C can also support functional programming to some extent with function pointers. Contrary to lambdas or functors, function pointers often lead to sub-par performance, as pointers obscure the original objects to some degree which makes inlining difficult. - Having first-class support of a particular programming paradigm greatly boosts productivity and performance. I tend to think of this as the main reason one programmer chooses a language over another, e.g., go functional with Haskell, or go object-oriented with Java. - However, supporting too many programming paradigms with core language features makes a language hard to manage. This is what C tries to avoid. #### Compared to other notable languages - Languages with garbage collectors (Java, Go, C#, Swift) are generally safer, as programmers do not manage memory directly, nor do programmers manipulate raw pointers freely, except in an `unsafe` block. - Could it be said that these languages are less flexible in terms of memory management? True, from a programmer's point of view, but not quite for a runtime tuner. - The same could be said about performance. However, tuning the language runtime is just as hard. - GC makes object destruction non-deteministic which undermines RAII. - D is special, for it allows programmers to opt in for a GC or not. - Rust is a strong competitor. I like to think of Rust as enforcing a sensible C++ programming scheme with the compiler and fencing potentially dangerous operations in `unsafe` blocks. ::: C++ is no longer C with classes; it better resembles Python with free-syntax. The standard library now boasts smart pointers, `<random>`, `<regex>`, `<chrono>`, `<thread>`, `<jthread>`, `<future>`, `<optional>`, `<variant>`, `<filesystem>`, `<ranges>`. At the time of writing, the most up-to-date compiler -- GCC10 -- fully supports all features of the latest language standard -- C++20 -- except 1. immediate functions (`consteval`), 2. `using enum` 3. class template argument deduction for aggregates 4. array size deduction in new-expressions, and 5. modules. ## Three Pilars 1. Iterators 2. Allocators 3. Executors ## Four Horsemen 1. Ranges 2. Concepts 3. Coroutines 4. Modules ## Executors