Результаты ежегодного опроса Annual C++ Developer Survey "Lite" за 2023 год наконец опубликованы, и мы можем почерпнуть из них ценную информацию об опыте C++ разработчиков. Одной из самых интересных целей этого опроса является выявление ряда болевых точек, с которыми приходится иметь дело C++ разработчикам.

В этой статье мы рассмотрим несколько узких мест в разработке на C++, на которые больше всего жаловались опрошенные разработчики.

Что из перечисленного вас больше всего раздражает в разработке на C++?

В этой категории было 16 вопросов. Респондентов попросили оценить серьезность каждой проблемы по шкале: “серьезная проблема” (major pain point), “небольшая проблема” (minor pain point) или “я не считаю это существенной проблемой” (not a significant issue for me).

Итак, три самых узких места по мнению опрошенных:

  • Управление библиотеками, от которых зависит мое приложение.

  • Время сборки.

  • Создание и настройка конвейера непрерывной интеграции с нуля (автоматизированные сборки, тесты и т. д.)

Также стоит отметить, что номером четыре в списке был пункт “Управление проектами CMake”, который, как мне кажется, связан с первыми пунктами.

Интересно, что для C++, широко известного (и критикуемого за это его пользователями) как большой и сложный язык, основные проблемы, похоже, связаны с инфраструктурой.

Одной из причин таких результатов, безусловно, является аудитория опроса. Более 50% опрошенных имеют опыт работы с С++ более 10 лет, а если считать тех, чей опыт работы превышает 5 лет, то мы и вовсе получим 80%. Так что для этой аудитории, я думаю, сам язык больше не является главной трудностью, поскольку эти пользователи научились с ним работать. А вот с инфраструктурой вокруг него до сих пор есть проблемы.

Давайте же разберем три самые неприятные болевые точки в порядке возрастания негодования пользователей языка.

№ 3: Создание и настройка конвейера непрерывной интеграции с нуля (автоматические сборки, тесты и т. д.)

Из примерно 1700 результатов 31.35% опрошенных считают это сильной головной болью, 40.85% — небольшой и 27,80% — несущественной.

Лично я удивлен, что этот пункт поднялся так высоко в рейтинге самых неприятных аспектов разработки.

GitHub или GitLab CI за последние несколько сделали очень много, чтобы помочь вам в развертывании ваших личных проектов. Если у вас нет проблем с зависимостями, о чем мы еще поговорим в следующих разделах, настройка конвейера CI/CD займет всего несколько минут после того, как вы освоите основы. Да, здесь есть некоторая кривая обучения, но с основами относительно легко разобраться. Это вполне реально сделать за полдня-день.

Касательно профессиональных проектов, я ожидаю, что настройкой CI/CD будет заниматься специально подготовленный человек или даже целая команда. Я полностью согласен с тем, что работа с такой организацией CI/CD или просто с другой командой может быть узким местом, и очень часто это именно так и есть. Но может быть тогда вопрос не об этом?

№ 2: Время сборки

Из примерно 1700 результатов 43.34% опрошенных считают это сильной головной болью, 37.56% — небольшой и 19.10% — несущественной.

Время сборки действительно может быть проблемой. Даже сразу по нескольким причинам. Проект может быть очень большим. Отсутствие управления зависимостями может вылиться в огромный монорепозиторий и кэширование не будет работать должным образом. Или же процессы сборки замедляют плохо настроенные антивирусные сканеры.

C++ пытается сгладить некоторые аспекты этой проблемы с помощью модулей в C++20. Также с ускорением процесса сборки могут помочь некоторые инструменты, например, ccache или distcc. Но для управления ими по хорошему необходимо выделять отдельного человека или целую команду. Еще больше помочь в преодолении этого узкого места могут инкрементальные сборки, так что проблема не так уж серьезна. За исключением того, что вам придется работать с одним заголовком, который все используют.

Но для развертываний, где вам желательно или даже необходимо собирать проекты с нуля, подготавливая сторонние библиотеки или создавая свою базовую систему Yocto, время сборки может быть реальной проблемой. И я предполагаю, что именно это подняло этот пункт так высоко.

№ 1: Управление библиотеками, от которых зависит мое приложение

Из примерно 1700 результатов 47.37% опрошенных считают это сильной головной болью, 35.09% — небольшой и 17.54% — несущественной.

Почти 50% респондентов считают управление зависимостями самой главной проблемой языка. Это много.

Управление зависимостями действительно представляет из себя проблему. Не все работают в Google, где бы вы могли сказать: а давайте не будем использовать OpenSSL и разработаем собственную криптобиблиотеку. Большинству проектов придется использовать то, что доступно.

Проблема начинается уже с систем сборки. Для библиотек C и C++ не существует стандартных систем сборки. Скорее всего, если вы используете 5 зависимостей, вам придется иметь дело с 3 разными системами сборки.

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

Если вы работаете на Windows и пишете под Windows, или на Linux и пишете под Linux (даже встроенный), вам может повезти, и вы найдете решение, которое идеально вам подойдет. И скорее всего именно так и происходит у людей, для которых этот пункт представляется небольшой или несущественной проблемой.

Но если вам нужно делать это для нескольких платформ, то это уже проблема совершенно другого масштаба. И здесь даже еще не идет речь о задаче отслеживания проблем безопасности в ваших зависимостях и реагировании на них.

И это еще не все: различные настройки компилятора, отладочные и релизные сборки, санитайзеры…​ на все это нужно тратить время и силы.

Компании очень часто упускают это из виду. Они хотят видеть реализованные фичи, а не тратить время на управление зависимостями. То, что фичи очень часто не могут быть реализованы без управления зависимостями, — это то, что приходит с практикой.

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

Vcpkg и Conan прекрасно работают во многих сценариях, но имеют свои ограничения. Такие инструменты, как spak, зависят от платформы. Другие подходы, такие как CPM или FetchContent, превращают проекты в монорепозитории, создавая другие проблемы. И у нас есть системы сборки, такие как meson или xmake, которые поставляются со своими собственными решениями для управления зависимостями. Кроме того, каждая используемая вами зависимость может иметь собственное представление о том, как она управляет своими зависимостями и как она хочет быть собрана. И как только вы решите все это, если вам нужно работать под несколько команд с разными требованиями, инструментами и культурами, ты перед вами воссияет уже совершенно другой уровень этой проблемы.

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

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

Подытожим

Каждый из этих пунктов может быть отдельным постом в блоге, эссе или даже книгой. Можно много об этом говорить, но суть в том, что существует проблема с инфраструктурой C++.

C++ в том виде, в каком он есть сегодня, возможно, не сможет решить эту проблему. По крайней мере, не в таком контексте взаимодействия стандарт C++ с разработчиками, ISO/JTC1/SC22/WG21. Я могу кое-чего в этом не понимать, но я думаю, что если мы хотим решить проблему в контексте стандарта, нам, возможно, придется рассмотреть ISO/JTC1/SC7 с его рабочими группами или что-то подобное. Возможно, это можно было бы реализовать в связи с ISO/JTC1/SC7/WG4 (Tools and environment). Я не уверен что это когда-либо произойдет, но кто знает.

Я не думаю, что эта тема может быть решена вне стандарта. Решения вне стандарта привели нас к тому, что мы имеем сегодня – самой острой болевой точке.

Есть ли такие же проблемы у других языков?

Тут есть нюансы. Нативно компилируемые языки имеют схожие проблемы. У Rust тоже есть проблема с временем компиляции. Golang компилируется удивительно быстро. Оба утверждают, что решили проблему управления зависимостями, но их решения все еще имеют ограничения и свои собственные проблемы. Оба имеют системы управления пакетами, которые извлекают исходный код из Git-репозиториев и собирают зависимости на компьютере разработчика. И оба по-прежнему часто зависят от известных C-библиотек, которые они ожидают найти в системе. Предварительно скомпилированные и доставленные другим менеджером пакетов.

Есть способы достичь того же результата и с помощью C++, используя один из менеджеров пакетов CMake, например CPM, или систему сборки, такую ​​как Bazel, которая может извлекать зависимости из Git-репозиториев и собирать их на лету.

Но у этого подхода есть ограничения по масштабу. Это значительно менее серьезная проблема для Golang с его сверхбыстрой скоростью компиляции, но, безусловно, проблема для Rust и C++. Ее можно решить только с помощью эффективных стратегий кэширования, что само по себе непросто. Но это уже тема для другого поста.


Скоро пройдет открытый урок, посвященный ускорению матричного умножения на C++. На этом занятии рассмотрим способы хранения матриц в памяти, сравним по скорости исполнения различные алгоритмы умножения и обсудим причины отличий во времени исполнения. В результате научитесь писать микробенчмарки на C++ с использованием библиотеки Google Benchmark и узнаете, как ускорить операции умножения матриц.

Записаться на бесплатный урок можно на странице специализации "C++ Developer".

Комментарии (7)


  1. x2v0
    31.05.2023 13:35

     как spak, зависят от платформы

    Правильное название Spack - Spack


  1. Rustified
    31.05.2023 13:35
    +1

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


    1. DancingOnWater
      31.05.2023 13:35

      В любом долгоживущем языке проблем с/, вызванных обратной совместимостью пруд-пруди. Но беда в том, что без оной, головняка в порядки больше. И если для библиотек, зачастую можно пережить (хотя на моей практике были и те случаи, когда ноша уже неподъёмна), то вот в конструкции языка - это ад.


      1. domix32
        31.05.2023 13:35

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


        1. DancingOnWater
          31.05.2023 13:35

          Мне всегда казалось, что модули изобрели уже после того, как C++ ушел в массы. А ввести модули пытались еще в С++11, но поняли что для этого надо некисло перелопачивать компиляторы. Дошли только сейчас.


          1. domix32
            31.05.2023 13:35

            некисло перелопачивать компиляторы

            Собственно это как раз второй уровень легаси. В 10-х годах другие языки стали набирать обороты и составлять конкуренцию в нишах плюсов и стали подгонять скорость появления новых фич как в компиляторах, так и в самом языке.


  1. snk
    31.05.2023 13:35

    У Гугла тоже проблема с систематизацией подхода добавления зависимостей. У них часть проектов с бейзелем собирается , часть с симейком. Сравните репу filament и medipipe. Но в обоих случаях: большинство зависимостей - либо физически скопированные морсы (как у случае с филаментом ), либо ссылка на внешнмй опенсорс гит репо (как в случае с бейзел сборкой мелиапайпа). Всякие либджепеги и тензорфлоу. Хотя я думаю, что здесь дело в том, что Гугл покупает эти проекты вместе с командой разработки , а не разрабатывает с нуля.