Incomplete interpretation of the father of C++ on the C++20 standard

Incomplete interpretation of the father of C++ on the C++20 standard

Author: Old 9.Technology

Video of Station B: C++ 20 Standard-40 Years of C++

Social: Zhihu

Public number: Laojiu School (the newcomers have surprises)

Special statement: originality is not easy, no reprinting or plagiarism is allowed without authorization, if you need to reprint, please contact the author for authorization

Preface

There is such a video on the tubing: CppCon 2019: Bjarne Stroustrup "C++20: C++ at 40" .

This is September 17, 2019. The father of C++ spoke at the C++ Conference in 2019. He started using "C with Classes" (the predecessor of C++) in 1979, and will end in 2019. Bjarne Stroustup Summarizes the 40-year history of C++, and finally produces a result: the stable version of the C++ 20 standard is presented to the majority of C++ developers.

Introduction to C++ History

We use the wiki as the standard to refer to the development history of C++. We will not refer to the above content anymore. Please understand it by your own Baidu translation. We are not focusing on the history of C++ today. Today we are interpreting the 40-year video of the development of C++ by Bjarne Stroustup, the father of C++.

The following illustration is accompanied by our explanation, hoping to help you quickly understand the description of the C++ language and its development process by the father of C++, so that you can learn C++ as soon as possible, the most popular and compelling programming language. The video we recorded has been uploaded to station B so that everyone can watch the corresponding video.

As a programmer in the Department of Computer Science and Technology, please do not understand all the reference translations and interpretations below as standards. Everyone should read an article such as game commentary or joking (because I am a C++ supporter, loyal fan~, all interpretations will inevitably bring subjective emotions and opinions), please read this article Just read it in a relaxed and happy mood. If there are any shortcomings, please correct me and add.

Features of C++ 20 version

The father of C++ summed up the features of the C++ 20 version in two words

  • stability--stability (stable pressure to everything)
  • evolution--update (advance with the times and reach the top of the trend)

Note : Comparing the photos of Bjarne Stroustrup in Bell Labs when he was young, I found that the old Bjarne is about to become a fairy. I think he is very handsome!

Does he look like now

Heiharchi, the hero in the game "Tekken"

Anyway, what do I think, he looks like this big boss now~ Like it!

C++ development history

1977 to 2019

Since 1979, C++ has been used in the development of the original landline phones, and our smart phones have been using C++ for development until now. C++ has never been interrupted in the application development of the underlying hardware.

The above illustration describes that in the past, telephone products used hardware interface products and now wireless interface smart phone products. Both of them use C++ written software drivers to be called by a third application.

Early 1980s

Ken and Dennis, the father of C language, just provide a product that can complete almost all functions without relying on assembly. It is a semi-portable system programming language-C language. There are two reasons to say that it is semi-portable:

  • C language has no function prototype
  • Lint just represents the state of the static program analyzer

Note : The concept of Lint is as follows

Simply put, lint is a programming language lexical and syntax analyzer.

The available memory of most computer applications is less than 1MB, and the operating frequency is less than 1MHz. Therefore, the high-tech things in this era are as follows:

  • Owning a PDP-11 16-bit small computer is very compelling
  • Owning a VT100 terminal means owning a work of art
  • A "personal computer" sells for about US$3,000 (that s the US$3,000 that was inflationary decades ago)
  • IBM PC is only a concept machine at this time

In this era, "everyone" "thinks" that the "object-oriented thinking" that everyone must talk about now is useless. The reason is simple:

  • OO stuff is too slow
  • There are too few places to use, and the requirements are very special
  • For most, it s too hard to understand

Into the 2019s

Here we discuss the features of the C++20 version:

  • New does not equal good or old, and new does not equal bad or old
  • This article is not aimed solely at C++ 98, C++ 14, C++ 20 versions, etc.
  • I will occasionally introduce the history of C++

This article does not discuss "details" because each technical point will be explained within one hour within this week.

Suggested learning methodology

The attitude of developers using C++

  • Focus on the essence of C++ (it is generally said that you can't just look at the surface of the problem, but the essence of the problem)
  • Use the "advanced features" of C++ only when needed

The attitude of C++ teaching staff is

  • Focus on the essence of C++
  • Don't hide the key features of C++ because of space limitations
  • Tell people three truths
    • there is only one truth
    • But the truth does not always appear
    • Keep adding details

What is legal and effective

Need better tool support, such as C++ core wizard

Principles and trade-offs of C++

  • C++ is a programming language that can be used for business definition, function realization and lightweight abstraction
  • Programming language design is not just a product for development, it should also include the following two points
    • The logic of continuity is the essence
    • Stability is everything
  • What C++ can do for code:
    • The world is unimaginably complex
    • The world is also chaotic
    • Most applications require stable pressure to everything
    • Generally speaking, C++ is "only one thing"
  • Support the "discretionary use" feature
    • Does not force developers to comply with certain "purely theoretical things" (such as object-oriented programming ideas)
    • Will not require only "expert" level developers to use
    • Principles of simplification of programming thought (complex things are simplified, simple things cannot be complicated)

C++'s high-level goals

The high-level goal of C++ is to follow the aka principle:

  • evolution
    • Stable (downward compatible, C++ 20 version compiler can compile and run C++ 98 version source program normally)
    • Support code upgrade
  • Simplification is the core of everything
    • Don't complicate complicated matters
    • Don't make complicated things self-willed
  • Zero cost principle
    • If you don t use it, we don t need to pay attention (also aka s "no divergence principle")
    • The functions we need, not everything we need to write by ourselves
  • High-level goals
    • The core function is designed by ourselves and implemented by software
    • The idea of our developers is the business function itself

Supplement: aka principles

I will not refer to the translation here anymore, please refer to Baidu for your own understanding. Because there are a lot of such boasting articles, we won't go into it here.

We change the world

For applications, the value of programming languages is to achieve the same quality of applications!

Software changes the world, embodied in the following two aspects:

  • Programming and design
    • Abstraction: express your ideas directly
    • Use better hardware
    • Code analysis and compilation build operations
  • Application field
    • Application areas of scalability and complexity
    • Engineers, scientists and other fields
    • ...

From 1979 to 2019, C++ has been widely used in very fields.

Key features of C++

  • The static type system supports both built-in types and user-defined types
  • Support value and reference semantics
  • Direct use of machine resources and operating system resources
  • System and general resource management
  • Support mixed software development model
  • Support object-oriented programming
  • Support compile-time programming
  • Support built-in concurrency through the library

Supplement :

I don't refer to translation here, everyone understands it by Baidu. There are many bragging articles on the Internet, I just briefly describe: the concept of compile time refers to the time when the application code is converted into machine code (such as binary code), and usually it appears before the runtime.

Static system

The static type system is the foundation of all C++ functions, and it supports the following core functions:

  • Compile time error detection
    • For example, list lst; ... sort(list);//error: Cannot access the linked list randomly
    • Error handling at runtime will result in high operating costs and higher complexity
  • effectiveness
    • Directly expresses our ideas, simple and efficient
    • Move internal calculations from runtime to compile time
  • Achieve flexibility through the solution of the compilation mechanism
    • Solve the problem of calculation overload, such as sqrt(2)
    • Generic programming, such as vector v; ... auto p = find(v,42);
    • Support meta (bit) programming (this is very popular in modern programming languages)
    • Compile-time diagnosis, such as static assertion of static static_assert (weekday(August/3/2019) == Sunday)

Note: It is precisely because C++ uses type detection, overload processing, static assertion and other processing at compile time, so it must take a long time to compile, so when we originally used C++ 11 to write games, we used it directly because of the sub-module design. Java and C# coding ideas are used for C++ programming (all functions are written, compiled, and debugged using a C++ project). As a result, after 30,000 lines of program code, the compilation speed is as simple as an old dog!

The difference between value and reference semantics

We need two concepts to describe the physique of things.

The semantics of the value can be assigned to any data type, as shown below:

x = y + z; //The variable type can be int built-in type, or complex<double>, or matrix, or other... x = y; //x is a copy of y; but x and y are separate They are all independent things. Just like the concept of deity and clone in fantasy novels. Copy code

Pointer/reference semantics can be assigned to any type, as shown below:

*p = x; //The value of x can be T*, and shared_ptr<T>, or something else ... p = q; //p and q point to the same thing. Copy code
  • handle--Handle (memory address allocated by the operating system)
  • value--value (something stored in memory)

Value type

  • Most types are values, such as integers, characters, strings, container types, etc.
  • Abstract semantics (usually refers to regular expressions)
  • Allocate memory space through the stack
  • Inline expansion
  • Generally implemented using pointers

Note: The concept of inlining is shown below

I will not refer to the translation here. Regarding the concept of inline, there are a lot of bragging opinions on the Internet, please refer to Baidu by yourself.

Pointer/reference type

  • All pointer types and reference types can "point to" one thing, such as T*, T&, unqiue_ptr, Forward_Iterator
  • One of the core goals of using pointers/references is to efficiently transmit information and data, such as
    • auto p = find(lst,"something interesting");
    • sort(v);
  • The second core goal of using pointers/references is to build non-dispersive things (data structures)
  • Both pointers/references use machine resources, so the most efficient effect can be achieved

About generics

The essence of generic programming is regularity. Regularity refers to the built-in data types of C++ as well as user-defined types. See the sample code below:

template <Element T> class Vector { public : Vector (initializer_list<T>); //... T* elem; //T* points to any legal data type in C++, including custom data types } //The type of parameterized Element when in use is as follows: Vector< int > vi = { 1 , 2 , 3 }; //C++ built-in data type Vector<complex< double >> vc = {{ 1 , 2 },{ 3 , 4 },{ 5 , 6 }}; //User-defined data type Vector<Vector< int >> vvi = {{ 1 , 2 , 3 },{ 4 , 5 , 6 },{ 7 , 8 , 9 }); //Nested type copy code

Direct use of machine resources

  • The main operation is to insinuate the machine instruction set:
    • Algorithm operation: +, -, *,/,%
    • Access operation: ->, [], (),...
    • Bit logic operations: &, |, ^ (exclusive or), ~ (complement), >> and << (shift), rotation
  • Memory is a set of serialized things, such as pointers are machine addresses as shown in the figure above
  • Objects can be simply combined in series, as shown in the figure above
    • Array
    • Class/structure
    • Note: handle also has its own value
  • Simple abstraction of hardware

Bit set

  • Manipulate bits of any size
  • &, |, ^&, |, ^ (exclusive OR), ~ (complement), >> and << (displacement), rotation

span

  • Sequence of operation objects, such as

    • Array array<byte, 1024> a;

      //...

      span s{a};//The size of the declared element type is not displayed

      for(const auto x: s) f(x);//No range error detection

      for(auto& x: s) x = 99;

      span s2{a, 512};//Specify a size span

      span s3{a};//Specify the span of the element type

Onion rule

  • Abstraction layer
    • The result of our abstraction is like an onion, the more abstract is stripped, then we cry harder
  • Average complexity management

Great God means: everything has two sides. If we play the concept of object-oriented encapsulation deeper, the complexity will inevitably increase. If you don t play with object-oriented programming ideas, the more code, the same complexity will increase.

Construction/deconstruction pair

Its object resource management architecture: see the Gadget class below

  • All object resources must be returned to the operating system after we use them
  • The user does not need to know which tool resource is used
class Gadget { Gadget (/*parameters*/ );//Initialize/construct an object //Get memory resources from the operating system ~ Gadget (); //Clear resources //...Copy and move... //.. .Reset the user interface... private : //...present... } Copy code

System general resource management

  • Each object is an independent resource, which is represented as

    • Need to clean up itself (destructor)
    • Cannot use built-in type pointers to manage this relationship
  • To calibrate the resource range, see the sample code below

    void f ( int n, int x) { Gadget g{n}; //We third-party developers don t need to know how memory resources are managed by the operating system. //... if (x < 100 ) throw run_time_erro{ "Weird!" }; //No memory will be produced Leak if (x < 200 ) return ; //No memory leak will occur //... } Copy code

Note : In C++ programming, we often see the wording of return, which is written to prevent memory leaks.

  • There are four ways to control the complex life cycle of an object: creation, copy, move and destruction. See example below
Gadget f ( int n, int x) { Gadget g{n}; //Object g may be very large //Object g may contain objects that cannot be copied //... return g; //There will be no memory leak because it is not complicated //No pointers //No Show statement memory management } Auto gg = f ( . 1 , 2 ); //Gadget object is moved to the outside of the f function, a further saving of gg variable duplicated code

It can be seen from the figure that the objects g and gg are two objects, but their content is the same, and the memory location is the same.

General Resource Management

  • Realize implicit memory resource release and safety guarantee
  • All C++ standard library containers will manage the elements it manages. These containers specifically include the following
    • vector
    • list, forward_list (singly linked list)
    • map, unordered_map (hash table)
    • set, multiset
    • string, path
  • Many C++ standard library classes manage non-memory resources, including the following
    • thread, jthred, shared_mutex, scoped_lock
    • istream, fstream
    • unique_ptr, shared_ptr
  • The container can contain non-memory resources, such as recursive operations, vector<forward_list<string,jthread>>

Module

Module is the most popular concept in modern programming languages. It is used everywhere in JavaScript, including the Qt framework language, which proves how powerful sub-module design and development are. The following is an example of using standard C++ module syntax:

export module map_printer; //Define a module import std; //Import modules, the order of import is not important import my_containers; export template <forward_range S> requires Printable<KeyType<S>>&& Printable<Value_type<S>> void print_map ( const S& m) { for ( const auto & [key,val]: m) //Split into key and value cout << key << "->" << val << '\n' ; } Copy code

  • The modules in C++ have the following main functions:

    • Minimize dependencies between objects

    • Avoid circular dependencies

    • Implement modular programming

      import A;

      import B;

      It has the same function as the following

      import B;

      import A

    • Only use the code in the imported module, which may adjust the size of the code

    • Only "copy" the code in the module once, and only parse it once

Assembly

C++ supports the following assembly methods:

  • Module
  • class
  • concept
  • template
  • function
  • Alias

Generic programming

According to the assembly strategy that can be used above, let's take a look at the current C++20 version of generic programming

  • Directly use types to allude to abstract business logic requirements, such as direct mapping of singly linked lists, integer types, etc.
  • Define business logic requirements as a conceptual type, see the sample code below
template < typename R> concept Sortable_range = random_access_range<R> //have begin()/end(),++,[],... && permutable< iterator_t <R>> //have swap() etc. && indirect_strict_weak_order<R>; //have<etc Copy code

How to use

void the Sort (Sortable_range Auto &) ; the Sort (vec); //the OK: to save a sequential number of columns in the Sort (LST); //error: trying to save a list as a sequence of style copy the code

  • Choose according to abstract requirements

    void sort (Sortable_rang auto & container) ; //The container must be sortable template < typename R> concept Forward_sortable_range = forward_range<R> && sortable< iterator_t <R>> void sort (Forward_sortable_range auto & seq); //No random access required Sort (VEC); //the OK: because of the use Sortable_range sorting Sort (LST); //Ok: because of the use Forward_sortable_range duplicated code
  • We can't say

    • "Forward_sortable_range is not as strict as Sortable_rangeg"
    • We calculate by definition

  • Generic programming (GP) "is a way of programming", including the following
    • Define an interface using concepts
    • Type designation and interface plus one layer
    • In principle, sort(v) and sqrt(x) are a little different
    • "Similar to ordinary programming, but exactly the same"
  • The sort function uses the <comparison method to sort by default, of course, we can also specify a different sorting method, see the sample code below
template <random_access_range R, class Cmp = less> require sortable_range<R,Cmp> constexpr void sort (R&& r, Cmp cmp = ()) ; sort (v,[]( const auto & x, const auto & y){ return x> y;}); sort (vs,[]( const auto & x, const auto & y){ return lower_case_less (x,y );}); Copy code

Object-Oriented Programming

I won't refer to the translation of this PPT, everyone can understand it. Let's just talk about one important point: object-oriented thinking can only be realized at runtime.

This PPT means that if we do not implement object-oriented programming ideas at runtime, then from the current point of view, we can only solve it through static storage solutions.

In the C++20 version, the overloaded() function will not be loaded in time. The current version of C++ is extensible

  • Build according to the needs of our third-party developers
  • Or use existing standards to construct
template <class... Ts> struct overloaded : Ts...{ //Collect N types using Ts::operator () ... ; //N types are called once }; //Parameter Type template derived Template <Ts of class ...> Overloaded (Ts of ...) -> Overloaded <Ts of ...> copy the code

Direct use of operating system resources

  • Simplified memory lock
mutex m1; int sh1; //Shared data mutex m2; int sh2; //Another shared data void Obvious () { //... scoped_lock LCK1 {M1, M2}; //Get two locks //shared data operations sh1 += sh2; } //lock release two duplicated code

  • "Double lock initialization" operation
mutex mx; //OS supports synchronous operation, the code cost is very high automic< bool > initx; //use the relatively convenient atomic variable int x; //share data if (!initx){ lock_guard lck {mx}; if (!initx) x = 42 ; initx = true ; } //...Use the x variable... copy the code
  • No data competition

Synchronized code is always written in a low-level way

mutex mx; automic< bool > initx; int x; if (!initx. load (memory_order_acquire)){ mx. lock (); if (!initx. load (memory_order_relaxed)){ x = 42 ; initx. store ( true , memory_order_release); } mx. unlock (); } //...Use the x variable... copy the code
  • In principle, do not abstract these low-level codes

Let me take a look at the implementation of thread synchronization code before the C++20 version

//example for thread::join # include <iostream> //std::cout # include <thread> //std::thread, std::this_thread::sleep_for # include <chrono> //std::chrono: :seconds void pause_thread ( int n) { std::this_thread:: sleep_for (std::chrono:: seconds (n)); std::cout << "pause of " << n << " seconds ended\n" ; } int main () { std::cout << "Spawning 3 threads...\n" ; std::thread t1 (pause_thread, 1 ) ; std::thread t2 (pause_thread, 2 ) ; std::thread t3 (pause_thread, 3 ) ; std::cout << "Done spawning threads. Now waiting for them to join:\n" ; t1. join (); t2. join (); t3. join (); std::cout << "All threads joined!\n" ; return 0 ; } Copy code

The original synchronization requires more than 20 lines to be written, but now only two or three lines are used.

Concurrent algorithm

Don't synchronize threads when you don't have to, let them play freely.

The C++20 version may not provide the sorting function of the concurrent version in time.

Compile time calculation

The C++20 version ported the past runtime calculations to compile-time calculations for the following reasons:

  • Based on execution efficiency and code elegance
  • Do it only once, instead of repeating a million calculations like in the past
  • No need for runtime error handles anymore
  • Constants no longer have data race issues

It can be used to solve the following problems when compiling:

  • Overloading and virtual functions
  • template
  • Variable template
  • Constant expression functions and user-defined types

Constant parameters are called at compile time.

Pay attention to the following sentence

<< {June WEEKDAY COUT/21 is/2016 } << '/n-' ; The static_assert (WEEKDAY {June/21 is/2016 } == on Tuesday); duplicated code

This way of writing is the most popular JSON syntax in JavaScript.

Use hardware directly

  • Function-use the memory stack frame directly
  • Coroutines (Coroutines)-use the memory call framework

Coroutine

Coroutine is a kind of generator and pipeline, it mainly depends on loading.

int main () { auto src = seq ( 2 ); //Infinite int sequence: 2,3,4,5,6,7,8,9,10,11,... auto s = sieve (src); //Filter non-prime numbers: 2,3,5,7,11,... auto t = take (s, 10'000 ); //Get the first 10,000 prime numbers: 2,3,5,... 104729 print (t); //Print prime numbers } Copy code

I won't refer to the translation of this PPT anymore, you can understand it right away.

This is the result of the coroutine calculation output.

Using is more convenient for us to redefine the type!

The core goal of coroutines is simple asynchronous programming.

Library

The C++20 version can easily use libraries written in any other programming language, while C++ can use libraries in other programming languages besides its own standard library.

I will not refer to the standard library for translation. Like other libraries, such as Boost, Qt framework programming library, this library is so easy to use.

Time processing

I don't refer to the translation of these two PPTs, because you can understand them at a glance.

What is C++20?

The C++20 version is the most important release after the C++11 version. It has the following features:

  1. Simple, elegant, faster coding speed and faster compilation speed
  2. Modular programming
  3. Concept definition
  4. Coroutine
  5. Range designation
  6. date
  7. Range span
  8. Better compile-time programming support
  9. A lot of small functions, but these functions are really important

  • C++ is a general-purpose programming language that defines and implements lightweight abstractions.
  • Not a complicated feature package
    • It is a set of ideas
    • It is a set of design principles
  • It goes through such an evolutionary process...->C++98->C++11->C++14->C++17->C++20->...
  • It is a standard WG21 (C++ standard protocol)

Features after C++20

There will be additional features in the C++23 version:

  • Standard module
  • Libraries supporting coroutines
  • Actuator and network programming

Possible features

  • Static reflection
  • Design pattern matching

**Note: **Maybe everyone is not sensitive to static reflection and design pattern matching. If C++ implements the reflection function, and the C++ language itself can match the design pattern, then it means that the most popular Java language should withdraw from the stage of history.

summary

C++20 is amazing!

Although, it is 2021, our VS 2020 version has not been released yet. However, we are still very much looking forward to the official application of the C++20 version in actual development.

At last

Remember to follow+Like+Favorite+Comment+Repost

Author: Old 9.School Technology

The copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source.