Яндекс corporate blog
Programming
C++
Compilers
IT Standards
March 6

Feature freeze C++20. Coroutines, Modules и прочее

На днях прошла встреча международного комитета по стандартизации C++ в американском городе Кона. Это была не просто встреча, а feature freeze! Никакие серьёзные новые идеи больше не могут просачиваться в стандарт, остаётся лишь пара встреч на добавление предварительно одобренных вещей, исправление недочётов и устранение шероховатостей.

Ожидать ли Модули и Корутины в C++20, будет ли там быстрая библиотека для форматирования вывода, сможет ли она работать с календарями, добавили ли std::stacktrace, начнёт ли компилятор сам вызывать std::move в ряде случаев, приняли ли std::flat_map? Всё это и многое другое ожидает вас под катом.



Coroutines TS


Самые жаркие дебаты разгорелись вокруг сопрограмм. Комитету предстояло рассмотреть три различных подхода к сопрограммам и решить, принимать в стандарт имеющиеся Coroutines TS, либо идти другим путём.

Выбор был не простой, у каждого подхода есть свои минусы и плюсы:

  • N4775:
    • + нет ограничений на то, что сопрограммы должны быть описаны в заголовочном файле
    • нет строгих гарантий, что не произойдёт динамическая аллокация
    • ± не самый простой интерфейс (P1477R0 это исправляет)
    • страшненькие ключевые слова co_await и co_yield (предложение P1485R0 от РГ21 это исправляет)
    • + 3 года применяются на практике

  • P1063R2:
    • + нет динамических аллокаций
    • сопрограммы должны быть описаны в заголовочном файле или самим надо хитровыкручиваться с type erasure
    • ещё более страшные ключевые operator[<-] и [->]
    • нет рабочего прототипа
    • не самый простой интерфейс для создания асинхронных вещей

  • P1430R0:
    • + нет динамических аллокаций
    • сопрограммы должны быть описаны в заголовочном файле или самим надо хитро выкручиваться с type erasure
    • + нет страшных ключевых слов, всё гладенько
    • + пользователи корутин не видят страшных корутиновых внутренностей (даже не видят co_await аналогов, всё из коробки работает)
    • первое предложение, ни разу не обсуждалось, требует кучи доработок
    • невозможно реализовать на текущих технологиях (требуют поддержки структур динамического размера), требуют огромных трудозатрат для реализации
    • ± немного напоминают лапшу из callback


После долгих дебатов сопрограммы были приняты в C++20 в том виде, в котором они были в Coroutines TS (с co_* префиксами и старыми точками кастомизации).

Modules


На обсуждение модулей повлиял один интересный документ с замерами производительности:
P1441R0. Трактовать результаты можно по разному: от «существующие системы сборки и реализация модулей ещё недостаточно оптимизированы» до «модули плохо масштабируются с ростом сложности проекта».

Помимо этого документа, комитет обсудил ряд небольших правок к текущим модулям. В итоге, спустя 15 лет обсуждения, прототипирования и экспериментов с внедрениями, модули были приняты в C++20.

Format


Good news everyone! Если не найдут фатальных недостатков в подгруппе Library, то в C++20 можно будет безопасно и очень быстро форматировать строки. Скажите «до свидания» std::ios, std::locale и прочим ужасам 90-х! Теперь Python подобный синтаксис для форматирования доступен из коробки в С++: P0645R5.

Более того, было принято предложение на интеграцию нового форматирования и календарных времён P1361R0. Если всё пойдёт по плану, то и даты можно будет выводить по-человечески!

Networking, Executors и Properties


Executors являются важным кирпичиком для поддержки Networking в C++ из коробки. Для Executors нужны Properties — возможность модифицировать тип данных, в зависимости от параметра переданного на этапе компиляции, не меняя концепт типа.

Properties описаны в P1393R0. Не смотря на то, что текста для включения в стандарт всего пара страничек, предложение вызвало бурные обсуждения. Предложение позволяет делать практически всесильные точки кастомизации, менять поведение любых функций, использующих Properties.

В итоге решено было Properties включать в язык только в C++23, а соответственно и Executors, и Networking в C++20 не появятся.

Прочее


В черновик C++20 уже были внесены следующие изменения:

  • Структуры без конструкторов (агрегаты) теперь можно инициализировать, используя круглые скобки P0960. На практике это значит, что теперь std::make_shared, std::make_unique, std::*::emplace* будут корректно работать с агрегатами без ошибок компиляции
  • Были добавлены функции lerp для линейной интерполяции P0811
  • Добавлена возможность векторизировать алгоритмы стандартной библиотеки P1001
  • Методы std::span теперь возвращают беззнаковые типы (по аналогии со всей стандартной библиотекой) + была добавлена функция std::ssize для получения размера контейнера в виде знакового числа P1227
  • Unordered контейнеры научились искать значения, используя заранее посчитанный хеш P0920

Много других вещей ожидают финального ревью в подгруппах Library и Core, для включения в C++20:

  • Эффективное ожидание на std::atomic; классы семафоров и барьеров P1135
  • std::flat_map P0429
  • std::flat_set P1222
  • std::function_ref P0792
  • constexpr для <cmath> и <cstdlib> P0533
  • std::ranges::to<любой-контейнер> для сохранения диапазона значений в контейнер P1206
  • Возможность эффективно извлекать строки из std::*stringstream и передавать во владение пользовательские строки P0408
  • Множественные правки для operator<=>, ranges, constexpr

Заслуги РГ21


В самый первый день за горячо любимое в Яндекс.Такси предложение на Stacktrace P0881R3 взялась подгруппа Core. Замечания по дизайну были дополнительно обсуждены в подгруппе LEWG, ещё раз проработаны в Core. В итоге в течении всей недели вносились правки и велись обсуждения. В черновик стандарта предложение ещё не включено, но должно оказаться в C++20 (если не найдут вдруг какой-то фатальный недостаток).

До обсуждения нашей идеи P1485R0 на приведение ключевых слов для корутин дело не дошло.

Также в SG1 Concurrency обсуждали идею concurrent unordered map P0652R2. Нас попросили перепроверить, что предложенное API позволяет избежать reader contention. Также сказали поисследовать concurrent unordered контейнеры, которые не имеют функции erase и не защищают значение контейнера от конкурентной модификации.

Предложение от ZaMaZaN4iK на специализацию std::hash для различных классов стандартной библиотеки P1406R0 решено было сильно порезать. Комитет порекомендовал оставить специализации только для std::pair, std::tuple, std::array и std::basic_string от пользовательских аллокаторов.

В подгруппе цифр SG6 обсудили механизм для взаимодействия различных новых классов чисел P0880R2. Предложение позволяет специализировать два шаблона, получить полный набор математических операций и сравнений для всех новых типов. По итогам обсуждения решили попробовать расширить механизм, чтобы им можно было пользоваться не только для нужд стандартной библиотеки, но и пользователи могли использовать эти операторы для своих типов.

Также обсуждали наши незначительные предложения, включая feature testing macro P1424R0 и политики на их добавление в стандарт.

Быстро обсудили нашу идею, позволяющую компилятору убирать лишние копирования R0889R1. Нам сказали продолжать работу в этом направлении и накидали примеров, которые не должны ломаться с новыми правилами.

Вместо итогов


C++20 будет так же разительно отличаться от C++17, как С++11 отличался от C++03. Огромное количество новых технологий и новых парадигм: Concepts, Contracts, Ranges, Modules, Coroutines, constexpr контейнеры и constexpr динамический полиморфизм, «ниблойды» и т. д.

В скором времени мы, Рабочая Группа 21, отправим комментарии к черновику стандарта C++20. Поэтому, если у вас есть какая-то боль или вы не согласны с каким-то нововведением, пожалуйста, оставляйте свои мысли на этой странице.

Следующее собрание международного комитета будет летом, на нём могут начать рассматривать нововведения для C++23. Если вы хотите что-то изменить в C++ или предложить свою идею, то всегда можете написать на https://stdcpp.ru/, где люди из РГ21 помогут вам донести ваши желания до комитета.

Желаете поговорить с нами вживую? Скоро состоится открытая встреча РГ21, следите за анонсами на events.yandex.ru. Так же ищите нас на апрельской конференции C++ Russia в Москве.
Что из C++20 вам больше всего пригодится в разработке?
9.1% Concepts 30
5.7% Contracts 19
36.2% Modules 119
23.7% Coroutines 78
7.3% Всё что связано с constexpr 24
10.9% Ranges 36
6.7% Прочие новинки стандартной библиотеки 22
Voted 328 users. Passed 153 users.
+85
18k 59
Comments 210
Top of the day