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, virtual
  • constexpr vector and string!
  • Chrono: calendar, time zone support
  • std::format - see std::format in C++20
  • std::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:

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++  

P0928R1

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  

P2043R0

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  

P2077R0

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  

P2073R0

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  

P2025R0

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?