C++ Club - Meeting 138

Episode Date: November 1, 2021

http://cppclub.uk...

Transcript
Discussion (0)
Starting point is 00:00:00 Welcome to the C++ Club. This is episode 13 for the meeting number 138 that took place on the 28th of October 2021. The October committee mailing is out. Papers! First, let's quickly see some of the papers that have been freshly adopted into C++23. Monadic operations for std optional. Cy Brand's proposal to add monadic operations to std optional makes it into C++23. These include map, or as we call it in C++ for some reason, transform, and underscore then, and or underscore else. Every other language that has an optional concept also has monadic operations for it, and now so does C++. You may not want to use these operations, but it's nice to have the option.
Starting point is 00:00:58 See what I did there? Deducing this. Quote. We propose a new mechanism for specifying or deducing the value category of the expression that a member function is invoked on. In other words, a way to tell from within a member function whether the expression it's invoked on is an L value or an R value, whether it is const or volatile, and the expression's type, end quote. This is very useful when implementing several overloads of the same member function to deal with constant ref qualifiers. The proposed syntax is to lift this into an actual member function parameter so that normal deduction mechanisms could be used.
Starting point is 00:01:45 Add support for pre-processing directives elifdef and elifendef. This is self-explanatory. I'm surprised it wasn't available before. Extend init statement to allow alias declaration. In C++20 you can use typedef in init statement but not using alias declaration. In C++20 you can use typedef in init statement, but not using alias declaration, which is a bit inconsistent, and this paper fixes it. Multidimensional subscript operator. We propose that user-defined types can define a subscript operator with multiple arguments to better support multidimensional containers and views.
Starting point is 00:02:28 Move-only function. This paper proposes a conservative move-only equivalent of std function. Zip. This paper proposes four new views. Zip, ZipTransform, Adjacent and AdjacentTransform and related functionality. The ranges feature gains more useful stuff. Printing volatile pointers. This fixes a quirk of stream output for volatile pointers which were being converted to other types like int or bool, because they couldn't be printed as normal const void pointer due to qualifier mismatch.
Starting point is 00:03:10 Byte swapping for fun and enough. This adds an efficient way to flip or swap or reverse all the bits of an integer type without having to resort to compiler intrinsics. Heterogeneous erasure overloads for associative containers. Quote, The authors propose heterogeneous erasure overloads for ordered and unordered associative containers, which add an ability to erase values or extract nodes
Starting point is 00:03:40 without creating a temporary key type object. End quote. Useful. Character sets and encodings. This is more long overdue improvements to Unicode string support. What is a view? This paper provides clarifications for the role of views in the ranges feature. The paper really stresses two points throughout. Views are lightweight objects that refer to elements they do not own, and views are constant-time, copyable, and assignable. Support std generator-like types in std format.
Starting point is 00:04:20 This enables formatting results of coroutine-based generator function results by switching std format to taking parameters by forwarding references instead of const references. It has been implemented in the fmt library since version 6. It's currently at version 8. Now some other papers that caught my attention. Standard library modules std and std.compat. Import std std imports everything in namespace std from C++ headers like stds fopen from CSTDIO. It also imports operator new etc. from the header new. Import std compat imports all of the above plus the global namespace counterparts for the C wrapper like fopen. I think this paper is on its way to be adopted into C++23. Distributing C++ module libraries. Daniel Rosso of Bloomberg proposes a convention
Starting point is 00:05:37 for distributing module-based libraries. Quote, this paper proposes a format for interoperability between build tools, compilers, and static analysis tools that facilitates the adoption of C++ modules, where libraries are distributed as pre-built artifacts, as opposed to the build system having access to the entirety of the source code. End quote. I can see how big firms need some sort of convention for their internal library distribution.
Starting point is 00:06:03 So this proposal will come handy as long as everyone follows the same convention. Just like compilers with their C++ module binary interface files. Oh wait. Closure-based syntax for contracts. Gajpa Rajman and his co-authors think that attribute-based contract syntax is too limiting. They propose a closure-based syntax instead, with three new context-sensitive keywords, pre-, post- and assert. The syntax is similar to the require syntax used for concepts.
Starting point is 00:06:41 The authors list some of the advantages of this syntax. Of the currently proposed attribute-based syntax, of which I especially like this one, quote, it's consistent with the rest of the language instead of inventing a yet another mini-language, end quote. I can see how this paper has the potential to cause a non-trivial amount of bike-shedding in the contracts study group. Honestly, after all the kerfuffle that happened with contracts, where a good enough solution was derailed at the last minute by those who wanted a perfect one, I lost all emotion towards contracts and now I'm just watching indifferently from the sidelines. Let us now look at another area that is totally going super well in the committee.
Starting point is 00:07:21 Networking and senders-receivers. There are three new papers. Ruminations on networking and executors. NetTS, ASIO and sender library design comparison. And response to P2464, the networking TS is baked. P2300, senders-receivers is not. The two sides, networking TS-ASIO and senders-receivers, are writing letters to each other in the form of proposals. The saddest thing is the fact that there are two sides. Nico Agiositis wrote a paper, P2012, proposing to fix a long-standing problem with a range for loop.
Starting point is 00:08:07 As it stands today, it's really easy to hit lifetime bugs that lead to a crash. When the expression iterated over contains more than one function call and one of the functions returns a temporary, its lifetime is not extended, which leads to undefined behavior the current solution seems to be warning about the possibly UB in code style guides the MISRA coding standards prohibit more than one function call in the 4-range initializer the UG votes acknowledged the problem strongly and were in favor of a solution that could break existing code. However, UG weren't sure about a new kind of safe loop.
Starting point is 00:08:57 Niko's proposed solution was to add range for loop to the list of cases where lifetime of temporary objects is extended. Quote, When a temporary object is created in the for-range initializer of a range-based for statement, such a temporary object persists until the completion of the statement. The lifetime of temporaries that would be destroyed at the end of the full expression of the for-range initializer is extended to cover the entire loop. On 29 September 2021, the paper got rejected by the committee. It didn't get enough consensus.
Starting point is 00:09:31 Disappointment was expressed on Twitter. Necuriosities. The C++ standard committee just decided they do not want to fix the broken range-based for loop for C++23. It's broken for 10 years now. They agree that there is a severe problem, but want a general lifetime solution. But nobody wants to do the work. To which Victor Zverovich replied, didn't know it was reviewed. Nikoyosotis says, that's the problem with now standardizing C++ online. Only a few people can always join and rule everything. To which Victor replies, yeah, it's been a total disaster.
Starting point is 00:10:13 So that's it then. There is no general lifetime solution and the range-for loop stays broken in subtle ways. Stringy templates Colby Pike, aka VectorofBool, wrote an article on his blog about using strings as template parameters. This is a feature of C++20 called non-type template parameters. An integer template parameter results in a new type for each value of the parameter. This has been supported for a long time. In C++20
Starting point is 00:10:47 we can use a class type non-type template parameters. Certain requirements have to be met by such class. All its members can only be of type valid as non-type template parameter or an array of such type. Colby Pike uses it to implement a fixed string template combined with a deduction guide it allows for an easy initialization that looks like a normal assignment fixed string equals hello whereas the type of the template is an array of characters
Starting point is 00:11:21 now that we have a string class that can be used as a template parameter, we can do interesting stuff like what Colby Pike calls stringy templates. You can implement name types with the name of the type represented by a string as a template parameter and make it so that you can only assign a certain type to instances of such a template. This is very interesting and I'll be watching for further posts on this topic. The code is available on GitHub. The Reddit thread mentions two projects that use similar techniques. Constaval Huffman, a C++20 utility for compressing string literals at compile time to save program space.
Starting point is 00:12:08 And CTRE. Fast compile time regular expressions with support for matching, searching, capturing during compile time or runtime. There is a third project called Metama, row polymorphism in C++20. This post is an attempt at implementing Haskell-type extensible records in C++20. The code is on GitHub. The author uses the cutting-edge Visual Studio 2022 Preview 5 for development. Quote,
Starting point is 00:12:40 Row polymorphism is a kind of polymorphism that allows one to write programs that are polymorphic on record field types, also known as rows, hence the name." This is like prototype-based inheritance in JavaScript, where you inherit objects instead of types, and then extend them by adding fields. The author uses a fixed string class, just like Colby Pike in the previous article. And that is it for today and I'll leave you with this tweet by Ben Porter. Quote, I'll sometimes leave a dangling else just as a threat to the compiler that it better run that if statement or else. Thanks for coming and I'll talk to
Starting point is 00:13:23 you next week. Bye!

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.