C ++ 20 and Modules, Networking, Coroutines, Ranges, Graphics. The results of the meeting in San Diego

    A couple of years remain before C ++ 20, which means that feature freeze is just around the corner. Soon the international committee will focus on combing the draft C ++ 20, and the innovations will be added already in C ++ 23.

    The November meeting in San Diego is the last before the feature freeze. What new items will appear in C ++ 20, which of the large things have been accepted, and what was rejected - all this is waiting for you under the cut.



    char8_t


    Added new data type char8_t . The array of these characters is the UTF-8 string:

    std::u8string hello = u8"Привет, мир!";
    // TODO: Вывести значение пока нельзя!//std::cout << hello; 

    At first glance, it seems that innovation is insignificant. But it is not.

    char8_t is the first step to ensure that the standard C ++ library out of the box supports UTF-8. There is still a lot of work ahead, to C ++ 20 it is clearly not complete.

    However, now char8_t is much more than char / unsigned char. Programs that use char8_t can work faster due to the fact that char8_t is not aliased to other data types. In other words, modification of a string or any variable will not cause the values ​​of variables to be re-read from memory:

    booldo_something(std::u8string_view data, int& result){
        result += data[0] - u8'0'; // переменная result изменилась
        return data[0] != u8'0'; // будет использовано значение из регистра для data[0] 
    }
    

    If we took char (std :: string_view) in the example, we would get a code in which we refer to BYTE PTR [rsi] several times . In the case of char8_t, this does not happen .

    Note that now u8 "hello" is an array of chat8_t, not an array of char. This standard change breaks backward compatibility with C ++ 11/14/17! A full list of changes related to char8_t is available in document P0482 . In the same document there is a list of examples when the code valid to C ++ 20 becomes invalid due to char8_t.

    constexpr


    For C ++ 20, many (and I among them) want to see containers in the standard that can be used at the compilation stage. This will allow to do fewer calculations at runtime, which means that when the application is running, less processor time will be spent. In this case, often, you will not have to change anything in the source code - everything will just start working faster, initialize at compile time, better optimized by the compiler ...

    San Diego greatly expanded the capabilities of the compiler and standard library for evaluating expressions at compile time:

    • try and catch can now be written in constexpr functions ( P1002 ).
    • dynamic_cast and typeid can be called in constexpr ( P1327 ).
    • Added consteval-functions (former constexpr!) - functions that can be calculated only in the constexpr context ( P1073 ).
    • Added the function std :: is_constant_evaluated () , which returns true if the function is currently being calculated at the P0595 compilation stage . Try without extreme necessity not to use std :: is_constant_evaluated (): it is very distinctive .
    • Changing the active union field is now also possible with constexpr calculations ( P1330 ).
    • An unimaginable set of classes and functions of the standard library is now labeled constexpr. They can be computed at compile time ( P1032 , P1006 ).

    At the next meeting, which will be held in the United States on February 18–23, 2019, it is planned to add to containers std :: string, std :: vector (and possibly std :: map) the opportunity to work at the compilation stage.

    All additions and edits are vital for upcoming reflection on C ++ 23/26.

    Other stuff


    Heterogeneous searches in unordered containers


    Starting with C ++ 20, it will be possible to further configure unordered containers and force them not to construct temporary objects during search operations:

    structstring_hash {// Без следующей строчки будут создаваться временные объекты!using transparent_key_equal = std::equal_to<>; 
      size_toperator()(std::string_view txt) const { returnstd::hash<string_view>{}(txt); }
    };
    using unordered_set_string = std::unordered_set<std::string, string_hash, std::equal_to<> >;
    template <classValue>
    usingunordered_map_string 
        = std::unordered_map<std::string, Value, string_hash, std::equal_to<> >;
    // ...
    unordered_map_string<int> map = { /* ... */};
    assert(map.contains("This does not create a temporary std::string object :-)"));
    

    A very useful thing, details can be found in document P0919 .

    std :: bind_front


    It has long been considered that std :: bind is a rather dangerous thing, which makes it easy to get hurt. Therefore, in C ++ 20, a simpler std :: bind_front function was added .

    It does not support placeholders, works correctly with ref-qualifiers and compiles a little faster. You can use it approximately like this:

    intfoo(int arg1, std::string arg2, std::vector<int>&&, std::string_view);
    // ...auto bound = std::bind_front(foo, 42, "hello");
    // ..int result = bound(std::vector{42, 314, 15}, "word");
    

    A comprehensive description is in document P0356 .

    std :: assume_aligned


    Hooray, now you can tell the compiler that the data we have aligned:

    voidadd(span<float> x, float addition){
        constauto size = x.size();
        float* ax = std::assume_aligned<64>(x.data());
        for (int i = 0; i < size; ++i)
            ax[i] += factor;
    }
    

    This will help the compiler to automatically vectorize loops and generate more efficient code. Additional examples can be found in document P1007 .

    void foo (const Concept auto & value)


    In P1141 , an abbreviated syntax was adopted for writing template functions and classes whose arguments must conform to the concept. For example, void sort (Sortable auto & c); means that sort is a template function, and that the type of the `c` variable corresponds to the Sortable concept.

    Micro optimizations


    The std :: optional and std :: variant classes are now required to have trivial destructors, copy / move constructors, and copy / move assignment operators if the template class parameters have trivial properties. This will help the compiler and the standard library to generate more efficient and compact code ( P0602 ).

    The std :: function move constructor must now be noexcept. If you have std :: vector <std :: function> and the constructors of std :: function were not previously noexcept, then working with such a vector will become several times more productive ( P0771 ).

    If you dealt with large arrays of numbers and used make_unique / make_shared, then sometimes the performance slightly subsided due to the fact that each element of the array was initialized to zero. Some specifically wrote new T [x] to not initialize each value. So, in C ++ 20, we added std :: make_unique_default_init and std :: make_shared_default_init . These two functions come from Boost and they do not oversimplify initialization ( P1020 ).

    Another added * _pointer_cast function that accepts rvalue. This helps to avoid unnecessary increments and decrements of the atomic counter when working with std :: shared_ptr ( P1224 ).

    Fixes


    In the magnificent document P0608 , the pain was removed by using the std :: variant:

    std::variant<std::string, bool> x = "abc";    // Ой! До C++20 `x` содержит `true`

    Another great document P0487 of the same author eliminates the rake, which was attacked by many:

    char buffer[64];
    std::cin >> buffer;    // Теперь гарантированно не переполняетсяchar* p = get_some_ptr();
    std::cin >> p;            // Теперь просто не компилируется

    Finally, they decided that in contracts the author of the class has the right to use private members of the class under the terms of the contract ( P1289 ):

    structint_reference {// ...intget()const [[expects: ptr_ != nullptr ]] { return *ptr_; }
    private:
       int* ptr_;
    };
    

    Networking


    So, we proceed to major innovations. And let's start with the bad: in C ++ 20, we don’t see work with the network out of the box. Postponed indefinitely.

    Modules


    For the good news, the EWG subgroup approved the design of the modules, so there is every chance to see them in C ++ 20. The final battle for the modules to be at the next meeting.
    About assembly speed and modules
    Consider that out of the box the modules will not give you a big increase in assembly speed.

    The next years will be spent by C ++ developers on optimizing compilers for working with modules and on optimizing module presentation.

    Also, it is worth noting that for the ideal build speed, you will most likely need to refine your code base and mark up the public and private interfaces of the export module.

    Ranges


    Ranges in C ++ 20 accepted. On the last day voting, the authors of proposal P0896 broke a long applause. The whole room was standing ovation. The beginning of the applause even managed to photograph, the happy author of the proposal - in the cap of this post.

    Here are a couple of examples of what you can do with ranges:

    #include<algorithm>std::ranges::sort(some_vector);
    std::ranges::find(email.c_str(), std::unreachable_sentinel, '@');
    std::ranges::fill(std::counted_iterator(char_ptr, 42), std::default_sentinel, '!');
    

    Coroutines


    We return to what we did not accept. Coroutines are not standard on voting. Perhaps this will happen at the next meeting, but the chances are not enough.

    Little insider
    Разработчк Boost.Beast твёрдо решил взяться за альтернативное предложение по сопрограммам. Они будут похожи на обычные функции, их размер будет известен на этапе компиляции, они не будут динамически аллоцировать память… но будут требовать, чтобы всё тело resumable функции было видно в месте использования корутины.

    Хорошо это или плохо, подоспеет ли прототип к следующему заседанию — это открытые вопросы.

    2D graphics


    The proposal for a two-dimensional graphics resurrected, continue to work on it. The author plans to throw a prototype into a public place (for example, in Boost), run in, collect reviews of 2D graphics experts from another standardization committee.

    Merit WG21


    At the meeting, we basically pulled stacktrace (which we love very much in Yandex.Taxi) to the C ++ standard. Now the draft document looks like this . I hope that remains quite a bit, and have time for C ++ 20.

    Difficulties
    Оказалось, весьма сложно описать стектрейс в терминах абстрактной машины (в этих терминах описан весь язык C++ в стандарте), учитывая, что в абстрактной машине нет стека, и функции могут располагаться в отдельной памяти, из-за чего и void* не может представлять адрес вызова, и имён файла, где описана функция, может быть несколько больше, чем 1, и компилятор может просто сгенерировать вспомогательную функцию, которая в файле нигде не фигурирует, и так далее.

    We also tried to add plugins to the standard (dynamic loading of libraries, an idea from stdcpp.ru ). Here we were waited by a failure - the offer was rejected. We take into account the errors and try later.

    Our old suggestion is to add the [[visible]] attribute to simplify the creation of dynamic libraries , suddenly picked up by another developer in document P1283 . We strongly supported the document at the polls, the first subgroup was passed, we hope for success.

    The idea of ​​simplifying work with std :: variant, namely, “Add comparison operators std :: variant with its elements” , was also rejected. The main objections are still scary to change the std :: variant, considering its problems with the designers (although after P0608) they will disappear. Let's try again.

    With a competitive unordered map ( P0652 ), on the contrary, everything was quite smooth: we were recommended to check a couple of alternative interfaces and were told that the proposal was almost ready for adoption at Concurrent Data Structures TS (although it is only planned so far).

    In the SG6 Numerics subgroup, we walked through most of the ideas that we had, proposed and slightly discussed the mechanism of interaction of various classes of numbers ( P0880 ). We are waiting for the start of creating Numbers TS, where all new and tasty classes of numbers should go.

    In the subgroup on the core of the language, we presented ideas about the “Infinite copy elision” , namely P0889. People really want something like that, but not in the form that was stated. We were sent directly to the compiler developers for advice.

    Well, as mentioned above, our Misc constexpr bits P1032 paper was adopted in C ++ 20. Now it will be possible to use at the compilation stage of the array, tuple, pair, everything you need to copy std :: string, back_insert_iterator, front_insert_iterator, insert_iterator.

    Instead of totals


    C ++ 20 promises to be quite entertaining: Concepts, Contracts, Ranges, Modules, working with time zones and many constexpr innovations.

    Soon we, Working Group 21, will send comments to the draft standard C ++ 20. Therefore, if you have any pain, or you do not agree with some innovation, please leave your thoughts on this page .

    We also invite you to our next C ++ meetings: The open meeting of WG21 in Moscow and St. Petersburg and C ++ Siberia 2019 in Novosibirsk.

    Only registered users can participate in the survey. Sign in , please.

    What new C ++ are you interested in?

    • 42.5% Coroutines 166
    • 35.3% Ranges 138
    • 31.7% Contracts 124
    • 36.1% Concepts 141
    • 60.7% Modules 237
    • 51.2% Networking 200
    • 26.1% Stacktrace 102
    • 17.4% 2D Graphics 68
    • 40.7% Reflections (and metaclasses) 159

    Also popular now: