
At the beginning of November, a meeting of the
WG21 international working group on C ++ standardization, in which
Yandex employees participated, ended in the American city of Issaca. At the meeting, they “polished” C ++ 17, discussed Ranges, Coroutines, Reflections, contracts, and much more.
The meetings, as usual, took a whole day + it was decided to reduce the lunch break by half an hour in order to have more time to work on C ++ 17.
Despite the fact that most of the time was devoted to the analysis of the shortcomings of the C ++ 17 draft draft, we managed to discuss several interesting and fresh ideas, and even bring to the standard what we were asked for at
cpp-proposals@yandex-team.ru .
Debriefing
The main task of the last (and the next meeting) is the analysis and correction of comments on C ++ 17 (if you are not aware of the major innovations of C ++ 17, then
you are here ). The comments were of two types - comments from WG21 member countries and comments from users / developers of the standard library. Comments from countries, according to tradition, are dealt with first of all (each comment is assigned an identifier consisting of a country code and a sequentially increasing comment number). This time more than 300 comments came. Here are
some of the most interesting and memorable ones:
')
RU 1: initialization of constant objects
Since 2000, C ++ has a problem with the initialization of constant structures. So, the behavior of the compiler suddenly depends on a number of completely unobvious factors:
struct A0 {}; const A0 a0;
The request to correct this behavior came to us at
cpp-proposals@yandex-team.ru from Ivan Lezhankin, we with the help of people from GOST issued it as a comment from the country and ... the behavior was corrected in C ++ 14 and C ++ 17. Now the above code should compile.
Where it can be useful:Extremely useful when refactoring. Previously, removing an empty constructor could break the project compilation:
With the corrected RU 1, it will be possible to change classes, removing empty constructors, and the code will continue to work. In this case, you can get a small performance gain: libraries that use metaprogramming sometimes have additional optimizations for classes that are std :: is_trivially_constructible; compilers are often better optimized by the constructors that they themselves generated, etc.
RU 2: invalid use of type traits
A wonderful way to shoot yourself in the leg, not to notice and die from blood loss:
#include <type_traits> struct foo; // forward declaration void damage_type_trait() { // is_constructible , . // // , . std::is_constructible<foo, foo>::value; } struct foo{}; int main() { static_assert( // , damage_type_trait() // std::is_constructible std::is_constructible<foo, foo>::value, "foo must be constructible from foo" ); }
Personally, I spent a week looking for a similar error in boost :: variant. Now the WG21 has noticed the problem and is working on fixing it. All chances that the C ++ 17 will be fixed and the compiler, upon seeing the code with invalid use, type_traits will produce a compilation error with a message detailing the cause of the problem.
Where it can be useful:It will help you not to make difficult detectable errors. Get rid of developers from many unpleasant surprises when using optional and variant, whose designers use type_traits.
RU 4 & US 81: constexpr char_traits
We and the United States found the same flaw. The problem is that the std :: string_view has a constexpr constructor, but the initialization of the object will still occur dynamically:
#include <string_view> // : // > error: constexpr variable 'service' must be initialized by a constant expression // > constexpr string_view service = "HELLO WORD SERVICE"; // > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // > string_view:110:39: note: non-constexpr function 'length' cannot be used // constexpr string_view service = "HELLO WORD SERVICE";
Our fix was adopted as a
fix (version p0426-1 was adopted, it is not yet available for general use).
Where it can be useful:The compiler will be able to better optimize the construction of std :: string_view, you can use string_view in constexpr expressions.
shared_ptr :: unique ()
One of the requests was that shared_ptr :: unique () should guarantee the memory synchronization of std :: memory_order_acquire.
And here we realized that many people do not know how to properly use this function in a multithreaded environment. So, proper use - do not use.
If shared_ptr :: unique () returns true and your implementation guarantees std :: memory_order_seq_cst, then ... that means nothing! The situation may change immediately after calling the function unique ():
- in another thread there may be a link to this shared_ptr and it is being copied right now
- in another thread may be weak_ptr which causes lock ()
As a result, it was decided to mark the unique () method as deprecated and describe in more detail all the problems in the description of shared_ptr :: use_count ().
Legendre function polynomials
One request that came to us at
cpp-proposals@yandex-team.ru from Moscow State University from Matthew Kornilov, we especially remember. It described a lot of interesting things related to mathematics. Some ideas are now in development by the author himself, and some managed to be sent as “editorial edits” to the standard and corrected directly at the meeting in Issaqua, after talking with one of the editors of the standard.
So, one edit that was especially remembered was that you had to rename the section “Associated Legendre polynomials”. Because the formula in the well section is not representable as a polynomial :-)
...The C ++ standard is a serious international document developed by specialists from all over the world, in which every word should be chosen in the most correct way and even minor logical contradictions should be excluded.
What makes this “school” mistake smile me even more :-)
Other
- Std :: variant will not be able to store references, void and C arrays (but you can still use std :: reference_wrapper <T>, std :: monostate and std :: array to achieve similar behavior).
- Work continues on adding deduction guildes to the standard library. There is every chance that
std::array a = "Hello word";
will work out of the box. - ZOS specialists came to the meeting with some comments on the std :: filesystem. The plans are to manage to make modifications to the standard at the next meeting in order to make std :: filesystem an even more versatile tool.
- The special "tag"
std::in_place<--->
may be removed in favor of several tags std::in_place, std::in_place_index<>, std::in_place_type<>
. Personally, I prefer the last version. But the majority, including the author of the universal tag idea himself, disliked it.
Discussions and ideas
As always, discussions and analysis of errors took place in several subgroups simultaneously. Being in 5 places at once is a difficult task, so it’s impossible to recount all ideas first-hand. Here are the most interesting discussions that we visited:
??? operator. () ???
We discussed alternative syntax and approach to operator. ().
The old syntax is P0416R1 | New syntax P0352R0 |
---|
template<class X> class Ref { X* p; public:​ explicit Ref(int a): p(new X{a}) {} ~Ref() { delete p; } operator. X&() { return *p; } }; struct Y { Y(int); void f(); }; Ref<Y> r {99}; rf(); | template<class X> class Ref : public using​ X { X* p; operator X&() { return* } public:​ explicit Ref(int a): p(new X{a}) {} ~Ref() { delete p; } }; struct Y { Y(int); void f(); }; Ref<Y> r {99}; rf(); |
In other words, instead of operator. (), It is proposed to use a slightly more understandable “inheritance, where the author of the class takes care of storing the object itself”. WG21 asked the author to work further in this direction.
operator <=> ()
operator <=> () or “operator spaceships” is an idea that emerged from the discussion of automatic generation of comparison operators. The committee was against starting generating default comparison operators and against generating comparison operators using constructions of the form bool operator <(const foo &, const foo &) = default ;. Then the idea was born on the sidelines:
- Make a comparison operator that returns immediately the values ​​less, equal, greater;
- With this operator, generate all comparison operators;
So far, the discussion did not go further, but it looks promising.
Reflections
The group was developing a compile-time reflection for C ++. They have the basic functionality, which they are almost ready to transfer to further discussion in other subgroups and to issue TS (technical specification) - improvements to the standard, with which users can start experimenting without waiting for the new version of the main standard.
Results
People at the meeting processed a huge amount of comments to the standard. More than 100 shortcomings were corrected, for which he thanks a lot!
On December 5, in Moscow, we are waiting for the
Russian WG21 to
meet Marshall Clow, chairperson of the Library Working Group at WG21 C ++, the developer of the standard library libc ++, by Boost.Algorithm. At the meeting, we will talk about our future plans and developments, you can ask questions about C ++ that interest you and offer your ideas for C ++ 2a; Marshall will tell about Undefined Behavior.
We are also pleased to present the official website of the working group
stdcpp.ru to discuss ideas for standardization, help in writing proposals. Now you can share your idea for inclusion in the C ++ standard, find out what others think about it and discuss the proposed ideas with other developers. Welcome!