Как мы ездили улучшать язык программирования С++

cover.jpg

Разработчик «Яндекс.Такси» Антон Полухин — о поездке в Международный комитет по стандартизации, рассмотрении заявок на улучшение С++ и о важности этих исправлений для всех пользователей.

Два года назад «Яндекс» объявил о создании рабочей группы для разработки стандарта языка программирования С++. Группа стала проводником для всех российских разработчиков, которые хотят внести свои предложения по улучшению языка на рассмотрение в Международный комитет по стандартизации (ISO).

Сегодня C++ — один из самых широко используемых языков программирования. На нём написан почти весь интернет и множество программ, которыми мы пользуемся каждый день.

На C++ выполнен почти весь Adobe. От качества языка зависят обновления Photoshop, Illustrator, Acrobate и Indesign — базовые инструменты для работы любого графического дизайнера и верстальщика. C++ стал основой программного обеспечения для электронной коммерции на Amazon — крупнейшем сайте, который заменил многим американцам и европейцам походы по магазинам.

Операционная система OS X, разработанная в Apple, написана не на одном языке, но, например, Finder (аналог «Проводника» на Windows) сконструирован на C++. Все файлы и папки вашего Macbook, тегирование, структурирование и поиск — всё это зависит от качества языка.

Сайт агентства Bloomberg, где в режиме реального времени публикуется вся мировая финансовая информация, файловая система и поисковик Google, «Яндекс», «Яндекс.Такси», MySQL для работы с базами данных — всё написано на C++. Язык использует NASA, Microsoft, Nokia, Vodafone, центр ядерных исследований CERN, Intel, IBM — перечислять знаменитые компании и аббревиатуры можно до бесконечности.

Появление объектно-ориентированного программирования

В незапамятные восьмидесятые годы, когда датский программист Бьёрн Страуструп начал работу над С++, компьютеры выглядели совершенно иначе и были менее производительны, чем сейчас. C++ вырос из скрещивания очень выразительного, но медленного языка «Симула-67» и C.

Язык С создавался для того, чтобы программистам не приходилось писать новую программу под каждую архитектуру компьютера, а можно было бы написать код один раз — он бы работал на любой платформе. Для того времени это был прорыв, даже сейчас язык C всё ещё используется для прошивки, например, бытовой техники и написания операционных систем.

Бьёрн Страуструп добавил в язык C парадигму объектно-ориентированного программирования. Позже российско-американский ученый Александр Степанов добавил стандартную библиотеку — набор функций, шаблонов, контейнеров и классов, которые можно применять как «черный ящик», не заглядывая внутрь, использовать уже готовые образцы.

Это значительно облегчило жизнь программистам, вооружив их инструментами и полуфабрикатами для быстрого приготовления программ.

Процесс стандартизации

Процесс защиты предложений на ISO не менее сложный и замысловатый, чем написание кода. Международная организация по стандартизации несколько напоминает отечественный ГОСТ. Если когда-нибудь у вас будет время, полюбопытствуйте и загляните в ГОСТ 19781–90, который кодифицирует программное обеспечение. Стандарт C++ — около полутора тысяч страниц текста, который обновляется каждые три года.

Заседания комитета проходят три раза в год. Каждый раз в новом городе и длятся по целой неделе. На заседании необходимо присутствовать очно. Довольно часто каждый рабочий день занимает более девяти часов. В комиссии сидит сам изобретатель языка Бьёрн Страуструп.

В течение дня рассматриваются комментарии — в первую очередь от стран, то есть от таких групп, как наша, которые представляют страну, а потом уже от отважных энтузиастов-одиночек. Бывает, что за день нужно обсудить 300 комментариев. Например, на встрече в ISO в Иссакуа, где обсуждался как раз C++ 17, решили сократить обеденный перерыв, чтобы больше времени осталось на разбор предложений и обработку ошибок.

Мы приезжаем на встречи вооружённые до зубов, у нас также есть правки-пожелания от всех, кто пишет на почту рабочей группы. Иногда часть простых изменений удаётся внедрить прямо на заседаниях — в качестве «редакторской правки». Так было в Иссакуа.

Матвей Корнилов из МГУ справедливо заметил, что формулу в разделе «Associated Legendre polynomials» нельзя представить в виде полинома. Редакторы стандарта сразу исправили название раздела на «Associated Legendre functions».

Мы побывали на пяти заседаниях — три из них прошли в Америке, по одному в Канаде и Швейцарии. За два года приняли шесть наших предложений — это большая цифра, учитывая, что обычно предложения могут рассматриваться по два-три года. Например, нам удалось убедить комитет решать одну из проблем другими методами, позволяющими не дублировать все контейнеры стандартной библиотеки.

Проблема контейнеров

Угроза появления дубликатов контейнеров возникла, как ни парадоксально, из-за необходимости облегчить преобразование кода на C++ в машинный код, что традиционно было ресурсозатратной задачей. В стандарте 2011 года появился спецификатор constexpr — он позволял создавать переменные и функции, а их расчёт производился на этапе компиляции.

Одно из предложений, внесённое другими на рассмотрение ISO, было создание нового контейнера, который можно использовать только в constexpr-функциях. Это необходимо для того, чтобы часть вычислений производить заранее, ещё до запуска, поставки программы, выделяя память в константные выражения. Этот контейнер дублирует контейнер vector, только предназначен для constexpr контекста.

В будущем это привело бы к тому, что все контейнеры стандартной библиотеки получили своего клона для constexpr контекста. Этого малополезного задвоения мы предложили избежать. Мы нашли способ модифицировать уже существующие контейнеры для этих же целей, создав один новый аллокатор constexpr_allocator. С его помощью можно «тюнинговать» все остальные.

Наше предложение было принято. Значит, пользователи языка будут использовать привычные классы-контейнеры, а стандартная библиотека не будет раздуваться как тесто на дрожжах.

Казус спецификатора

Ещё пять наших принятых предложений касались спецификатора constexpr. Мы предложили исправить недочёт с циклами, которые не всегда гарантированно просчитывались в процессе компиляции, хоть и были помечены constexpr. Пометить некоторые простые методы как constexpr и проработать заголовочный файл »», чтобы он также вписывался в контекст constexpr.

Эти три предложения позволяют пользователям языка делать вычисления на этапе компиляции, используя привычные алгоритмы, а не переизобретая то, что уже есть в стандартной библиотеке. Наше предложение о модификации string_view приняли. Теперь программы будут быстрее запускаться, так как отныне переменные string_view можно инициализировать также на этапе компиляции.

И последнее, что нам удалось защитить, что внесено в стандарт — это реверанс в сторону математиков и физиков, использующих программное обеспечение в повседневных исследованиях. Теперь std: complex можно использовать в constexpr — это значит, что на этапе компиляции можно делать вычисления над комплексными числами.

Предвычисление комплексных констант увеличивает производительность программ, что вероятно когда-нибудь приведёт какого-нибудь математика к гениальному открытию.

Вместо эпилога

Стандартизация языка, как построение коммунизма — процесс бесконечный. В 1994 году собирались довести до идеала С++ к следующему году. В 2003 выпустили улучшения для «идеальной версии». В 2011 году выпустили стандарт С++ 11, который даже удостоился благодарности на вручении Оскара в 2018. В 2018 году программисты-энтузиасты и мы в их числе, всё еще бьёмся над улучшениями.

Можно подумать, что мы боремся за собственное удобство, за то, чтобы нам было проще и приятнее писать код на С++. Это правда, но отчасти. C++ производительный язык, но сложный и местами громоздкий. Из-за этого страдают не только разработчики, но и вся отрасль в целом, так как на выполнение некоторых задач в идеальном мире должно уходить намного меньше времени, чем уходит сейчас.

Каждое принятое изменение — это не просто очередная программистская примочка. Каждое новшество делает процесс разработки чуть проще, логичнее и быстрее, а работу наших приложений, нашу жизнь ещё лучше и технологичнее.

Сейчас на рассмотрении комитета 12 наших предложений. Это число будет расти. Любое принятое предложение, даже любая небольшая правка делает язык C++ чуть лучше, чуть проще, чуть функциональнее.

Десяток таких правок — и ваша любимая игра уже работает быстрее, ещё десяток — и ваш телефон меньше ест батарею. Ещё сотня — и у разработчиков по всему миру появятся новые инструменты для написания программ. А с новыми инструментами откроются и новые возможности.

©  vc.ru