Last Update:
Five Awesome C++ Papers for the Prague ISO Meeting and C++20 Status
Table of Contents
Continuing the tradition for other ISO C++ Meetings, I prepared a blog post where you’ll learn about:
- The current status of C++20
- an overview about the Prague ISO C++ Meeting (10th till 15th February 2020)
- a few interesting papers that are worth reading
Let’s start!
Disclaimer: the view presented here is mine and does not represent the opinion of the ISO C++ Committee.
What’s Already in C++20
Here’s a short list of things that are in the new standard:
- Modules
- Coroutines
- Concepts With Standard Library Concepts
- Ranges
constexpr
support:new
/delete
,dynamic_cast
,try
/catch
, virtualconstexpr
vector and string!- Chrono: calendar, time zone support
std::format
- see std::format in C++20std::span
std::jthread
You can also read my previous blog post about the Belfast meeting or have a look at the C++ at the end of the year article, where I listed a few more parts.
There’s also a C++20 Reference Card: https://www.cppstories.com/2020/01/cpp20refcard.html
The Prague Meeting
The meeting might already start my city - Cracow - is in the same time zone as Prague. The event is mostly about solving the national body comments for the Standard, so we won’t see any new features… and hopefully, we also shouldn’t see any removals. Since last year, the Cologne meeting the Standard is now in the feature freeze mode.
If time allows the committee will discuss papers that target C++23 and beyond.
Upcoming Meetings
The next meeting - where the C++20 draft will be ready for the last publication efforts - will be in Varna (Bulgaria). Probably during the meeting, the committee will discuss new things for C++23, and maybe some of the new parts will be voted in.
You can always find the list of ISO meetings here: Upcoming Meetings, Past Meetings: Standard C++
Awesome Papers
The papers (mailings) for meeting “Pre-Prague” can be found under the following link: JTC1/SC22/WG21 - mailing2020-01.
or in a easier-to read form:
- 2020-01 pre-Prague mailing available (1 of 2) : Standard C++
- 2020-01 pre-Prague mailing available (2 of 2) : Standard C++
There are so many papers that it’s tough to keep up with all of them, but below you can find a few that caught my attention. I tried to skip the “big” things and focus on something maybe less attractive, but still important.
Let’s start with something scary - Spectre!
P0928R1 Mitigating Spectre v1 Attacks in C++
To maximise the performance, in most modern CPUs, we have various forms of code speculations. The most common technique is through a branch predictor. The CPU tries to predict which path of an if statement will be executed and then runs it ahead. When the result of the condition is the same as the prediction, then we have a win situation. But in the other case, the CPU has to “revert” and execute the correct branch.
The result of that “guess” execution, even if it’s to be forgotten by CPU can be observed by various side channels. In some cases, it’s very unsafe - especially when you can observe some critical/private data.
Now, most of CPU has fixed the issues, via a system patch or even hardware solutions. But maybe it’s better to have fine-grain control over that fix?
In our code, a lot of places are not sensitive to such data leakage, and we don’t want to pay the price of reduced performance.
The paper shows several code examples, in C++, that explain some unsafe code and its risks. The authors also discuss a possible mechanism that would allow developers to get the best performance while keeping the critical code parts protected.
One solution might be extra attributes: like [[speculative_load_hardening(true)]]
that would then translate to instructions like __mm_lfence();
or some forms of “Speculative Load Hardening”.
I think the proposal might be quite crucial as it allows you to have more control over the system. I’d like to see a regular code to be “spectre safe” by default, but if I want, I can skip that extra safety and allow a bit more performance. Of course, the important bit here is that you have to be a real security expert if you want to allow that unsafe path and be sure about the safety of your code.
Don’t constexpr
All The Things
Since the introduction of constexpr
we can execute more and more code at compile time. But sometimes it feels unnatural and hard due to the limitations and complexity. It’s also hard for non-experts to fully leverage the capabilities of the constexpr
metaprogramming model.
But what if we could execute all code at compile time? With just a tiny change in the code?
The paper describes how we could use a really interesting C++17 compatible compiler that allows some powerful features (reflection, pattern matching!) plus the @meta
code execution!
It’s called Circle
The example that shows the core capabilities, and might be good advertisements is as follows:
#include <iostream>
@meta std::cout << "Hello at compile time!" << std::endl;
int main() {
std::cout << "Hello at run time!" << std::endl;
}
And then when compiling:
$ circle test.cpp
Hello at compile time!
$ ./test
Hello at run time!
As you can see std::cout
or stream operators are not redefined with constexpr
, but the compiler knows how to execute them at compile time. The trick is to enable special compiler runtime to handle the code.
You can also have a look at this CppCast episode with the author of the whole project Baxter - see here: Cicrle with Sean Baxter - CppCast
Of course, I don’t expect to throw away all constexpr
code and move to Circle model for C++23. Still, we might get some good lessons on how to make code more natural for compile-time evaluations and also improve the learning/teaching experience. What do you think? Do you like the new alternative for constexpr
?
Another paper which is linked to Circle P2062R0 and tries to extract some essential parts from that model.
Heterogeneous erasure overloads for associative containers
Following the addition of heterogeneous lookup for ordered containers in C++14 (see my post about that for C++14) and also for unordered containers in C++20, we can now think about extending that approach for other member functions. One of the best examples is that we can use string_view
or const char*
to find or erase elements in the container where the key is std::string
- there’s no need to create extra copies of the string object, just for the comparison.
The paper proposes to add new overloads for the .erase()
functions.
The authors also show the performance improvements of around 20% when using the new approach.
One problematic thing is that there’s an overload for const iterator
and iterator
, so the new overloads must reject such cases, The compare object must also have is_transparent
subtype exposed, similar as for the heterogeneous lookup. And for unordered containers we need Hash::transparent_key_equal
to be exposed.
Debugging C++ coroutines
This is an interesting paper that shows some real issues with working with coroutines. This early adoption paper might help the compiler teams to improve their support and focus on the core parts of the developer experience.
The authors ported a web socket server into coroutines and shared their experience. They used early GCC implementation and Visual Studio 2019 16.5.
For the debugging the authors stresses the importance of having visible local coroutine values and input arguments. Ability to seat a breakpoint inside a coroutine, or see promise_type object of the currently running coroutine.
I think it’s good to see such reports as they will definitely help when the C++20 is ready and shipped in our favourite toolchains. It’s not just the compiler that should work, but also debugger and even source code editors that are important for our productivity.
Guaranteed copy elision for named return objects
Since C++17 we have the guarantee that “copy elision” will happen for more or less unnamed objects returned from a function. For example
widget setup_widget(int x) {
return widget(x);
}
But if you want a named returned value optimisation (NRVO) then there’s no guarantee, most of the time the compiler can omit the copy, but still, the type has to be copyable.
The authors discuss options to enable NRVO and guarantee it.
For example for cases like
widget setup_widget(int x) {
widget w;
w.set_x(x);
return w;
}
Your Turn
What are your favourite features that might be included in the next Standard?
I've prepared a valuable bonus for you!
Learn all major features of recent C++ Standards on my Reference Cards!
Check it out here: