Мысли о современном C++ и игровой разработке

Original author: Ben Deane
  • Translation
Новый год для игровых разработчиков начался с волны критики, обрушившейся в адрес комитета по стандартизации C++ после публикации Араса Пранкевичуса «Жалобы по поводу современного C++». Возник серьезный вопрос: действительно ли комитет стандартов потерял связь с реальностью, или все наоборот, и это игровые разработчики откололись от остального С++ сообщества?

Вашему вниманию предлагается перевод популярного поста Бена Дина, — ветерана игровой индустрии, проработавшего продолжительный срок в компаниях Blizzard, Electronic Arts и Bullfrog в качестве разработчика на C++ и тимлида, — в котором он отвечает на критику с позиции собственного опыта.

TL;DR: Комитет по стандартизации C++ не имеет скрытой цели игнорировать нужды игровых разработчиков, а «современный» C++ не собирается становиться «неотлаживаемым» языком.
На протяжении всей прошлой недели в Twitter шла активная дискуссия, в ходе которой многие программисты – особенно те из них, кто работает в сфере игровой разработки – высказались о том, что нынешний вектор развития «современного C++» не отвечает их потребностям. В частности, с позиции обычного игрового разработчика, все выглядит так, будто производительность отладки в языке игнорируется, а оптимизация кода становится ожидаемой и необходимой.

В силу того, что на 2019 год я успел проработать в игровой индустрии более 23 лет, у меня имеется собственное мнение, основанное на наблюдениях по данной теме применительно к игровой разработке, которым мне и хотелось бы поделиться. Важна ли для игровых разработчиков «отлаживаемость» и почему? В чем заключаются вопросы, связанные с ней?

Для начала — небольшой экскурс в историю.

Многие игровые разработчики, пишущие на C++, работают в Microsoft Visual C++. Исторически сложилось, что вокруг платформ Microsoft сформировался огромный рынок для игр, и это отразилось на типичном опыте рядового игрового программиста. В 90-ые и 2000-ые большинство игр писалось с учетом этих обстоятельств. Даже с появлением консолей других производителей и ростом популярности мобильных игр, достоянием многих AAA-студий и многочисленных игровых программистов на сегодняшний день являются инструменты, произведенные Microsoft.

Visual Studio — это, возможно, самый лучший отладчик для C++ на свете. Причем сильнее всего Visual Studio действительно выделяется именно по части отладки программ — больше, чем своими front-end, back-end, реализацией STL или чем-либо еще. В последние пять лет Microsoft добилась серьезных успехов в развитии инструментов для разработки на C++, но даже и до этих заслуг отладчик в Visual Studio всегда был очень крутым. Так что когда вы занимаетесь разработкой на ПК с Windows, у вас под рукой всегда есть дебаггер мирового класса.

Учитывая вышесказанное, давайте рассмотрим процесс получения кода, в котором не будет багов; имеющиеся у нас возможности с точки зрения программиста, который не занимается играми; а также ограничения, с которыми сталкиваются игровые разработчики. Если перефразировать основной довод в пользу «вектора развития современного С++», то он сведется к типам, инструментам и тестам. Следуя этой мысли, отладчик должен выступать последней линией обороны. Прежде, чем мы ее достигнем, у нас имеются следующие возможности.

Возможность №1: Типы


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

  • значительное расширение type traits;
  • такие нововведения, как nullptr и scoped enum для борьбы с наследием C — слабой типизацией;
  • GSL и вспомогательные инструменты;
  • концепты в C++20.

Некоторым из вас может не нравиться метапрограммирование шаблонов; другим может не нравиться стиль написания кода, при котором почти повсеместно используется auto. Вне зависимости от этих предпочтений, здесь явно прослеживается основной мотив для использования перечисленных стилей в C++ — это стремление помочь компилятору, чтобы он в свою очередь мог помочь нам, используя при этом то, что он знает лучше всего: систему типов.

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

Откровенно говоря, вы легко можете проигнорировать время компиляции — но только при условии, что вы — программист в очень большой компании, которая не занимается играми и обладает устоявшейся внутренней инфраструктурой и бесконечными вычислительными мощностями для того, чтобы скомпилировать любой код, который вы только можете написать. Подобные огромные компании обеспокоены стоимостью компиляции — поэтому используют модули — но, как правило, у отдельных разработчиков боли это не вызывает. В то же время, для большинства игровых программистов это совсем не так. У инди-разработчиков нет ферм для создания сборок; разработчики AAA-игр часто используют что-то вроде Incredibuild, но, учитывая тот факт, что они запросто могут работать с кодовой базой, которой исполнилось 10 и более лет, процесс сборки все еще может занимать 15-20 минут.

Мы можем поспорить насчет относительной стоимости добавления «железа» против стоимости времени программиста, и я согласен с позицией, что «железо» обходится дешевле, однако:

  • Аппаратные средства — это реальные разовые расходы, которые будут возложены на бюджет текущего квартала, в отличие от не столь осязаемых расходов во времени/найме/и тому подобном, которые будут распределены на больший период времени. Люди плохо справляются с решением в пользу такого компромисса, а компании специально построены таким образом, чтобы оптимизировать краткосрочную прибыль.
  • Инфраструктура требует поддержки, и почти никто не идет в игровую индустрию для того, чтобы стать релиз-инженером. В сравнении с другими областями, где используется C++, зарплата игровых разработчиков не настолько велика — а не-игровым инженерам платят здесь еще меньше.

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

Возможность №2: Инструменты


Мы должны использовать максимум доступных нам инструментов — предупреждения (warnings), статический анализ, санитайзеры, инструменты динамического анализа, профилировщики и прочие.

Мой опыт говорит, что игровые разработчики используют эти инструменты там, где это возможно, но здесь у индустрии в целом имеется несколько проблем:

  • Данные инструменты имеют тенденцию лучше работать на платформах, не связанных с Microsoft — и, как упоминалось ранее, это не является типичным сценарием в игровой разработке.
  • Эти инструменты в большинстве своем нацелены на работу со «стандартным» C++. В них «из коробки» поддерживается std::vector, но не мой самописный класс CStaticVector из гипотетического движка. Безусловно, винить в этом инструменты бесполезно, но это по-прежнему один из барьеров в их использовании, который приходится преодолевать разработчикам.
  • Создание и поддержка CI-цепочки, которая будет запускать все эти инструменты, требует присутствия релиз-инженеров — и, как упоминалось ранее, найм людей на инженерные вакансии, не связанные непосредственно с играми, является системной проблемой для игровой индустрии.

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

С чего бы начать ответ на этот вопрос? Пожалуй, с очередного экскурса в историю игровой разработки:

  • До начала 90-ых, мы не доверяли компиляторам C, поэтому мы писали игры на ассемблере.
  • С начала и до середины 90-ых, мы начали доверять компиляторам C, но мы все еще не доверяли компиляторам C++. Наш код представлял собой C, в котором применялись комментарии в стиле C++, и нам больше не требовалось все время писать typedef-ы для наших структур.
  • Около 2000 года в мире игровой разработки произошла революция C++. Это была эпоха паттернов проектирования и больших иерархий классов. В то время поддержка STL на консолях оставляла желать лучшего, а миром тогда правили именно консоли. На PS2 мы навеки застряли с GCC 2.95.
  • Примерно в 2010 году предпринимаются еще две революции. Боль от использования больших иерархий классов стимулировала разработку компонентного подхода к коду. Это изменение продолжает свою эволюцию и сегодня в виде архитектур Entity-Component-System. Рука об руку с этим шла вторая революция — попытка воспользоваться преимуществом многопроцессорных архитектур.

В ходе этих сдвигов парадигм постоянно изменялись и сами платформы игровой разработки, причем изменялись серьезно. Сегментированая память уступила место плоскому адресному пространству. Платформы стали многопроцессорными, симметричными и не очень. Игровым разработчикам, привыкшим работать с архитектурами Intel, пришлось привыкать к MIPS (Playstation), затем к специальному «железу» с гетерогенными CPU (PS2), после этого к PowerPC (XBox 360), затем к еще большей гетерогенности (PS3)… С каждой новой платформой приходили новые рабочие характеристики для процессоров, памяти и дисков. Если вы хотели добиться оптимальной производительности, то вы были вынуждены переписывать ваш старый код, причем много и часто. Я даже не стану упоминать то, как сильно на игры повлияло появление и рост популярности Интернета, а также ограничения, которые накладывали на разработчиков держатели платформ.

Исторически сложилось, что реализации STL на игровых платформах были неудовлетворительными. Не является секретом и то, что STL-контейнеры слабо подходят для игр. Если прижать игрового разработчика к стенке, то возможно он признается в том, что std::string — вполне себе ОК, и std::vector — разумный вариант по умолчанию. Но у всех контейнеров, содержащихся в STL, имеется проблема контроля аллокации и инициализации. Во многих играх приходится беспокоиться по поводу ограничения памяти для различных задач — и для тех объектов, память для которых скорее всего придется выделять динамически во время геймплея, часто используются slab или arena аллокаторы. Амортизированное константное время — недостаточно хороший результат, поскольку аллокация потенциально является одной из самых «дорогих» вещей, что могут произойти во время выполнения программы, и мне не хочется пропускать кадр только из-за того, что она произошла тогда, когда я этого не ожидал. Я, как игровой разработчик, должен управлять своими требованиями к памяти заранее.

Похожая история получается и для других зависимостей в общем. Игровые разработчики хотят знать, на что уходит каждый цикл процессора, где и когда и за что отвечает каждый байт памяти, а также где и когда контролируется каждый поток выполнения. До последнего времени, компиляторы Microsoft меняли ABI с каждым обновлением — поэтому, если у вас было много зависимостей, то перестраивание всех их могло быть болезненным процессом. Игровые разработчики обычно предпочитают небольшие зависимости, которые легко интегрируются, делают всего одну вещь и делают ее хорошо — желательно с API в стиле C — и при этом используются во многих компаниях, находятся в открытом доступе (public domain) или имеют бесплатную лицензию, которая не требует указания автора. SQLite и zlib — хорошие примеры того, что предпочитают использовать игровые разработчики.

Помимо этого, индустрия игр на С++ имеет богатую историю больных синдромом «Not invented here». Этого следует ожидать от индустрии, которая начиналась с одиночек-энтузиастов, которые мастерили что-то свое на совершенно новом оборудовании и не имели никаких других вариантов. Игровая индустрия, помимо прочего, единственная, где программисты указываются в титрах без определенного порядка. Писать разнообразные штуки весело, и это помогает вашей карьере! Гораздо лучше строить что-то свое, чем покупать готовое! А поскольку мы так беспокоимся о производительности, мы можем адаптировать наше решение таким образом, чтобы оно подходило именно для нашего проекта — вместо того, чтобы взять обобщенное решение, бездумно тратящее имеющиеся ресурсы. Неприязнь к Boost — основной пример того, как подобное мышление проявляется в игровой разработке. Я работал на проектах, которые прошли следующий путь:

  • Для начала, для решения той или иной проблемы мы подключаем к проекту библиотеку из Boost.
  • Все работает очень даже хорошо. Когда нужно обновиться, возникает небольшая боль, но не больше, чем при обновлении любой другой зависимости.
  • Другая игра хочет использовать наш код, но камнем преткновения становится то, что мы используем Boost — несмотря на то, что наш опыт использования Boost прошел вполне нормально.
  • Мы убираем код с использованием Boost, но теперь перед нами встает новая проблема: мы должны решить задачу, которую до этого вместо наш решала библиотека из Boost.
  • Мы по сути копируем части кода Boost, которые нам нужны, в наши собственные пространства имен.
  • Позже, мы неизбежно и раз за разом сталкиваемся с тем, что нам нужна дополнительная функциональность, которая уже была бы в оригинальном коде, если бы мы его не выкинули. Но теперь владельцами этого кода являемся мы сами, поэтому нам приходится продолжать поддерживать его.

Нам не нравится что-либо огромное, пытающееся сделать слишком много дел одновременно или способное повлиять на время компиляции — и это вполне разумно. В чем люди ошибаются снова и снова, так это в том, что они противостоят тому, чтобы принять предполагаемую боль сегодня — в то время как из-за этого решения их ждет весьма реальная и гораздо большая боль при поддержке чего-либо за счет чьего-то еще бюджета, которую им придется испытывать в течение трех следующих лет. Увы, но наличие доказательств в виде игр, успешно использующих блюдо из STL и Boost, никоим образом не может повлиять на психологию человека и переубедить игровых разработчиков.

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

Вполне разумно подыскать улучшенную альтернативу std::map, или применить small buffer optimization в std::vector. Гораздо менее приемлемо быть обреченным на поддержку своих собственных реализаций algorithms или type traits, что не принесет практически никакой пользы. Как по мне, прискорбно, что STL для большинства разработчиков — это одни лишь контейнеры. Поскольку при изучении STL на старте обучают именно им, то говоря об STL большинство подразумевает std::vector — хотя на самом деле им следовало бы думать про std::find_if.

Возможность №3: Тесты


Утверждается, что должно осуществляться экстенсивное тестирование, TDD и/или BDD должно покрывать весь код, который можно покрыть, а с багами необходимо бороться написанием новых тестов.

Поэтому давайте обсудим тему тестирования.

Судя по моему опыту, автоматизированное тестирование в игровой индустрии практически не используется. Почему?

1. Потому что корректность не столь важна, а реальная спецификация отсутствует


Будучи молодым программистом в игровой индустрии, я быстро избавился от мысли о том, что я должен стремиться моделировать что-либо реалистично. Игры — это пускание пыли в глаза (smoke and mirrors) и поиск коротких путуй. Никого не волнует, насколько реалистична ваша симуляция; главное, чтобы она была увлекательной. Когда у вас нет другой спецификации, кроме как «игра должна ощущаться правильно», отсутствует сам предмет тестирования. Благодаря багам геймплей может даже становиться лучше. Достаточно часто баг попадает в релиз, и даже завоевывает любовь пользователей (вспомните того же Ганди из Civilization). Игры отличаются от других сфер, в которых используется C++; здесь нехватка корректности не приводит к тому, что кто-то в итоге лишается своих сбережений.

2. Потому что это тяжело


Разумеется, вам хотелось бы производить автоматизированные тесты везде, где вы сможете. Это может быть осуществлено для некоторых подсистем, для которых есть четко сформулированные конечные результаты. Юнит-тестирование в игровой индустрии, конечно, присутствует, но как правило ограничивается низкоуровневым кодом — упомянутыми ранее аналогами STL, процедурами преобразования строк, методами физического движка и т.д. Те случаи, когда у исполняемого участка кода есть предсказуемые результаты, обычно тестируются юнит-тестами, хотя TDD здесь и не применяется — поскольку игровые программисты предпочитают упрощать себе жизнь, а не наоборот. Но как вы протестируете код геймплея (смотрите пункт первый)? Как только вы выходите за рамки юнит-тестирования, то сразу встречаетесь с еще одной причиной, почему тестирование игр является настолько сложным.

3. Потому что в него вовлечен контент


Тестирование нетривиальных систем возможно будет включать в себя предоставление контента, с участием которого оно будет осуществляться. Большинство инженеров не слишком хороши в плане изготовления этого контента своими силами, так что для получения осмысленного теста потребуется привлечь кого-либо с нужными навыками создания контента. После чего вы столкнетесь с проблемой измерения того, что вы получаете на выходе — ведь это больше не строка или число, а изображение на экране или звук, которые изменяются с течением времени.

4. Потому что мы его не практикуем


Юнит-тестирование — это функция, для которой мне известны возможные входы и выходы. Однако геймплей — это непредсказуемое, складывающееся динамически поведение, и я не знаю, как подобное явление можно было бы как следует протестировать. Что я могу протестировать — если, конечно, я получу разрешение от своего менеджера уделить этому достаточное время — это, например, производительность, или высокоуровневые возможности вроди матчмейкинга, которые я могу проанализировать. Подобная инфраструктурная работа может быть увлекательно для некоторых игровых программистов, но большинству она попросту неинтересна, — да еще и вдобавок требует одобрения и поддержки со стороны владельца кошелька. В роли игрового программиста, я никогда не имею возможности заняться практикой написания высокоуровневых тестов.

5. Поскольку [компания] не видит необходимости в автоматизированном тестировании


Наша главная цель — это выпустить игру. Мы живем во времена индустрии, которая движется вперед за счет хитов, которые зарабатывают большую часть своих денег в первый месяц продаж, когда расходы на маркетинг этих хитов максимальны. Жизненный цикл консолей научил нас тому, что код в любом случае проживет не так уж и долго. Если мы работаем над онлайн-игрой, то скорее всего получим дополнительное время на тестирование матчмейкинга или нагрузки на сервера. Поскольку для релиза игры нам требуется, чтобы ее производительность была в порядке, мы должны как минимум произвести тестирование производительности, но мы не должны автоматизировать этот процесс. Для менеджмента в индустрии игр автоматизированное тестирование — это не более, чем трата времени и денег. Для его проведения приходится нанимать опытных инженеров, которые произведут работу, результат которой будет практически незаметен. Это же время можно было бы потратить на разработку новых фич. В краткосрочной перспективе для тестирования игры гораздо выгоднее использовать персонал QA, что приводит нас к следующему пункту.

6. Потому что в целом тестирование относят в играх к второсортной деятельности


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

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

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

К ним относятся, как к шестеренкам в огромном механизме, которых часто перебрасывают между проектами без предупреждений и в целом относятся к ним так, будто с их работой может справиться любой. Когда проект «съезжает» с даты дедлайна, инженеры могут ощутить кранч на своей шкуре, но QA достается гораздо сильнее, ведь им приходится работать в ночную смену и по выходным, плюс им же еще и достается за то, что они приносят невеселые новости о текущем состоянии качества проекта.

Им серьезно недоплачивают. Самые опытные тестировщики с годами экспертизы в предметной области получают меньше половины того, что платят разработчику среднего уровня. Мне приходилось работать с умнейшими QA-инженерами, которые создавали пайплайны для тестирования производительности с трекингом и оповещениями, создавали фреймворки для тестирования API и для нагрузочного тестирования и выполняли множество других задач, якобы недостойных времени «настоящих инженеров». Я уверен в том, что эти умнейшие люди получали бы гораздо больше, если бы работали в любой другой большой технологической компании.

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

Они вынуждены подчиняться. Тестировщикам часто говорят не беспокоить других инженеров. Когда им нужно сообщить о баге напрямую, их просят обращаться к инженерам уважительно, вроде «Миссис Х.» или «Мистер Y.». Иногда мне звонило раздраженное начальство QA-отделов — в тех случаях, когда я для совместного расследования связывался напрямую с теми, кто обнаруживал баг.

Все это звучит как страшная сказка, и пусть сталкиваться с подобными вещами приходится далеко не всем, к несчастью это происходит все еще довольно часто; настолько часто, что инженеры начинают думать — возможно, сами находясь под грузом постоянного стресса, но это их не извиняет — что работа QA состоит в том, чтобы искать их же баги, или, что еще хуже, начинают винить QA за баги.

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

Производительность отладки


С учетом всего вышесказанного — привычки заниматься отладкой, платформой для API и инструментов, которая до сих пор взрослеет, и сложностью (в совокупности с недостатком культуры) автоматизированного тестирования — становится ясно, почему игровые разработчики так настаивают на возможности отладки.

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

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

Другими словами, мы хотим иметь производительную отладку, потому что для того, чтобы ловить баги, нам часто нужно иметь возможность выполнять запуск приложений с достаточно большими и репрезентативными наборами данных. Но на самом деле, когда мы достигаем этой точки, то обычно дебаггер становится слишком грубым инструментом для использования — вне зависимости от того, производителен он или нет. Конечно, установка точек останова на данных (data breakpoints) может быть полезна для поимки проблем среднего размера, но что делать, если мы столкнемся с реальными багами — теми, которые остаются после того, как мы казалось бы уже все пофиксили? С теми самыми, которые возникают под нагрузкой в сети, или в случае нехватки памяти, или работающей на пределе возможностей многопоточности, или случаются лишь для небольшого, еще не идентифицированного подмножества на фоне миллиона других игроков, или возникают только на дисковых версиях игры, или только в сборке на немецком языке, или спустя три часа, проведенных за тестированием стабильности (soak testing)?

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

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

При использовании «современного С++» я пользуюсь отладчиком тем же самым образом, что и обычно. Я прохожу им по свеженаписанному коду; ставлю брейкпоинты на тех данных, которые меня интересуют; использую дебаггер для того, чтобы исследовать незнакомый код. С приходом «современного C++» ничего из этого не меняется, — и да, даже несмотря на то, что STL использует _Уродливые _Идентификаторы, это не делает STL магией. Иногда бывает полезным посмотреть, что STL делает «под капотом», или же переступить через нее; или, как теперь можно сделать, использовать отладчик для того, чтобы скрыть код библиотеки от меня.

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

Я сам был обеспокоен проблемой того, что код на C++ требует все больше и больше оптимизации, и я интересовался мнением разработчиков компиляторов по этому поводу. Факт состоит в том, что здесь нет однозначного ответа. Мы уже находимся в континууме, и у нас есть возможность продвигаться дальше в этом направлении без причинения вреда возможности отладки кода. Сегодня наши компиляторы выполняют copy elision (пропуск копии) для временных объектов, даже если мы не просим их производить данную оптимизацию. На нашу возможности отладки приложений это никак не влияет. Сомневаюсь, что мы станем жаловаться на то, что отладочные билды стали включать NRVO или еще полдюжины оптимизаций, которые могут быть произведены таким образом, что во время отладки мы их и не заметим. Подозреваю, что C++ движется как раз в этом направлении.

Эпилог: Путь современного С++


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

1. Ничего не делать


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

Это совершенно адекватная стратегия поведения для тех, кто работает на себя или с командой единомышленников. C++98, вместе с некоторым набором более новых функций, по-прежнему хорошо подходить для того, чтобы писать на нем игры.

Однако, если вы работаете в большой компании, то рано или поздно вам придется столкнуться с изменениями в языке, поскольку вам придется увеличивать команду и нанимать новых людей. В свою очередь, когда вы будете нанимать C++-разработчиков, это будет означать найм разработчиков на «современном» C++. Произойдет смена поколений — как это уже приключилось с ассемблером, C и C++98. Вы сможете управлять процессом, если установите ограничения на то, что разрешено в вашей кодовой базе, а что – нет, но и это решение не спасет вас в долгосрочной перспективе. И что вам делать в таком случае?

2. Принять участие


Вместо того, чтобы раз в год ездить лишь на одну GDC, начните посещать CppCon, где вы получите гораздо большую пользу от денег, потраченных вашей компанией на билет. Участвуйте в обсуждениях стандартов; вступайте в группы и подписывайтесь на рассылки; читайте черновики стандартов и предоставляйте авторам обратную связь. Если вы сможете еще и посетить встречи комитета, то это будет просто отлично, но даже если и нет — вы все еще можете сделать многое для того, чтобы донести до других вашу точку зрения.

Участие в комитете по C++ открыто для всех. Вся необходимая информация для тех, кто хочет принять участие в работе SG14, или SG7, или SG15 — или любой другой рабочей группе, касающейся сферы ваших интересов — может быть найдена на isocpp.org. У комитета нет никаких тайных планов — в самом деле, вы и правда считаете, что свыше 200 программистов могут согласовать между собой единую повестку? Здесь даже у «начальства» комитета зачастую не удается «пропихнуть» свои идеи.

Если вы хотите, чтобы ваше мнение было услышано, то вы должны начать говорить там, где ваше мнение может быть услышано, а не на Twitter или Reddit. Пожалуйста, воспользуйтесь этим советом — я с нетерпением ожидаю нашей дискуссии.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 60

    +6
    Вариант 3 — переходите на Rust.
      +1

      В процессе перехода.


      Из минусов можно отметить сложность в процессе освоения и некую сырость языка (стандартного графического фреймворка нет, возможностей по-человечески создавать игры тоже). Думаю, что второе довольно быстро исчезнет, а первое — нет. Язык и среда будут лишь усложняться.


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


      Выучить Rust — хорошая идея. Если он не будет Вашим основным языком, то Вы точно повысите свой уровень как программиста. Rust мультипарадигмальный, но вроде и не ООП, и не функциональный, и не процедурный. Всего по-немногу, всё грамотно сконструировано для грамотного применения.

        +2
        стандартного графического фреймворка нет

        Прям в std чего-то такого никогда не будет, конечно. А если в более широком смысле, то проект https://github.com/gfx-rs/gfx очень сильно на эту роль пытается претендовать, хотя недавний гигантский рефакторинг всего проекта сильно пошатнул его стабильность.


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

        Не уверен что это значит, но есть надежда что амбициозный проект https://github.com/amethyst/amethyst постепенно таки родит неплохой модульный игровой движок. Работы там, правда, тоже море еще.


        Еще для 2д игр есть намного менее амбициозный и простой https://github.com/ggez/ggez (вариация на тему love2d), на котором я свою хобби-игру потихоньку ковыряю.

        0
        Эх! Если в Rust с объектами было бы получше!
        Постоянно на него облизываюсь, но каждый раз останавливает нужда в ООП.
          +3
          А вы попробуйте. Скорее всего окажется, что острой нужды в ООП на самом деле нет :).
            +1

            В этом месте обычно принято говорить про ECS (Entity Component System) и кидать ссылку на доклад Катерины, тем более что речь в статье о разработке игр, где этот подход последние годы получает все больше признания.

            0

            Как правильно писал автор — разработчики игр, в основной массе, пользуются Visual Studio.
            И вот здесь начинаются проблемы с растом.
            Все мои попытки настроить Visual Studio под Раст закончились почти ни чем.


            Постоянно вижу восторженные посты о расте, но лично у меня пока совсем не получается насладиться им в силу выше описанной проблемы :(

              +1

              Visual Studio или Visual Studio Code? Настроить первое под rust — это какая-то безумная идея. :) Вряд ли visual studio будет его когда-нибудь поддерживать.


              Лучше, на мой взгляд, развивать IDE-плагин на платформе IntelliJ IDEA. Сейчас этот плагин пилят в том числе и люди из JetBrains, возможно, когда-нибудь оно превратится в полноценную и мощную IDE для rust от JetBrains.

                  –6

                  VS в принципе пора выкидывать как из за нацеленности на одну платформу, так и из за закрытости

                    +3
                    Так выкиньте, что Вам мешает? Ааа, огромное количество пользователей и отсутствие внятных аналогов…
                      +1

                      Попробуйте QtCreator — бесплатный, быстрый, кроссплатформенный, заточенный под C++. И не смотрите, что в названии Qt — этот фреймворк там поддерживается, но не навязывается.

                        0

                        Сорри, что влезаю — я попробовал — VS примерно настолько же мощнее QT Creator, насколько он мощнее блокнота. Да маленьких проектов норм, для больших, да при сложной отладке, да в сложной среде… вообще нет.

                          0

                          А можете привести пример того, что было полезного в VS, чего не было в QtCreator? Не для холивара, мне действительно интересно, поскольку есть опыт работы с QtCreator с проектом где-то 500 kLOC и как-то проблем именно связанных с IDE особо не ощущалось.

                            –3

                            Удаленная отладка, поддержка C++/CX, интегрированное тестирование, профайлеры разных видов, подтягивание дебажных символов для виндовых библиотек… Тонкие настройки компилятора, логично работающая система с solutions. И просто "все работает". В QT Creator всегда было ощущение наколеночности и бесконечных костылей.

                              +1
                              Удаленная отладка, поддержка C++/CX, интегрированное тестирование, профайлеры разных видов, подтягивание дебажных символов для виндовых библиотек… Тонкие настройки компилятора, логично работающая система с solutions. И просто «все работает». В QT Creator всегда было ощущение наколеночности и бесконечных костылей.

                              А вы точно с creator работали? Удаленная отладка уже как года 4 точно я пользуюсь. По стандартам ничего не скажу. Тестирование тоже уже появилось, но не пользовался им, как и виндовыми либами.
                              Тонкие настройки задаются легко через qmake, можно к ним условия применять. Все изменения легко в diff видеть.
                              И у меня там не просто «все работает», а летает и грузится в миг в отличие от комбайна VS)
                              Ну и напомните сколько вы отдали за лицензию VS)
                                0

                                Ну вот у меня другой опыт. В VS все как-то едино — и solutions, и настройки, все точно также в гите, но это все в единой системе — а не отдельно IDE, отдельно qmake, отдельно иногда cmake, в итоге каша. Хотя вполне может работать, я охотно верю, но для меня QT Creator — это странная эрзац-VS для QT, не более чем — типа, ну на безрыбье хотя бы так. А если учесть, что VS поддерживает не только C++, и оно бывает тоже надо (хотя бы C#)…


                                За лицензию VS ни разу не платил — либо пользовался Express Editions (там кое-чего нет, но база вся есть), либо по программе BizSpark получал бесплатно — это очень несложно. Не хачил VS, по-моему, никогда.

                                  0
                                  А CI у вас есть? И если да — настройки сборки там из sln берутся, или какими-то отдельными средствами? Ну и я бы не сказал, что отдельно CMake, отдельно IDE — это плохо, для меня это скорее плюс. В общем, видимо на вкус и цвет…
                                    +2

                                    Есть, конечно, и собирается прямо тот же sln напрямую, никаких отдельных настроек: msbuild project.sln. Все работает...

                                0
                                ser-mk в общем-то уже ответил примерно то же, что я хотел написать, могу только добавить что «тонкие настройки компилятора» — еще как есть, включая замену компилятора на любой другой. И все благодаря тому, что система сборки отдельно, IDE отдельно. Просто это не флажками в GUI, а «кодом» в CMake, и это реально удобно, особенно когда нужно сделать что-то хитровывернутое.
                                  +1

                                  Охотно верю, что в этом качестве qmake/cmake куда мощнее, чем sln, но пока не было нужно. А вот сама IDE, как писал выше, ну сильно удобнее.

                                +2
                                чего не было в QtCreator?

                                Кривоватая поддержка свежих C++, включая всякие там C++17. С приездом clang-кодомодели стало лучше, но не дотягивает.
                                Околонулевая поддержка cmake-проектов с несколькими таргетами (мне всерьёз предлагалось для их переключения лазать в настройки проекта и ручками прописывать что мне надо).


                                После второго я понял, что эта IDE мне не подходит совсем, и закрыл.


                                Но это именно то, чего не было. Не знаю, есть ли это в VS, я так-то с KDevelop и CLion сравниваю.

                                  0
                                  " С приездом clang-кодомодели стало лучше, но не дотягивает."
                                  вот как раз в емейл-рассылке QtC сейчас эту тему активно обсуждают, кстати.
                                0

                                deleted, случайно два раза отправилось

                                +1
                                Однажды пробовал QtCreator — надо было дебажить на Linux-е. В тот раз работа с ним вылилась в постоянное залезание в дебри для конфигурации настроек, которые в VS настраиваются или из коробки, или одним кликом. Отсутствие нормального понятия «проект»: в VS через solution есть доступ к любым настройкам на вкус и цвет — в Qt по праздникам можно дописывать comand-line для компилятора (ну разумеется я помню на память все аргументы gcc). Отладка по сравнению с VS — очень не удобно, ну и я не проверял, но встроенных тулзов типа профилировщика производительноти всего на свете в Qt тоже видимо нет.
                                Да, это первое субъективное впечатление, не претендующее на полную корректность, но все же это был реальный кейс работы над существующим проектом в Qt — и в общем это было не слишком приятно.
                                  +1
                                  Хм, у меня прямо противополжный опыт, подозреваю, что это связано с тем что я в обратной ситуации — лет 5 QtCreator был основным инструментом разработки, а MSVS использовался только когда припрет что-то очень специфичное сделать (типа экспортера для 3dmax).

                                  > работа с ним вылилась в постоянное залезание в дебри для конфигурации настроек, которые в VS настраиваются или из коробки, или одним кликом. Отсутствие нормального понятия «проект»: в VS через solution есть доступ к любым настройкам на вкус и цвет

                                  Отлично все настраивается в CMake, нормально хранится в системе контроля версий и git log при изменениях конфигурации сборки показывает вполне человеческие диффы (как кстати с этим в случае с sln-файлами?). Да, надо знать CMake. Зато не надо помнить в какой из 10 вкладок находится нужная галочка.

                                  > Отладка по сравнению с VS — очень не удобно

                                  Что имеено неудобно? Пошаговая отладка есть, watch есть, точки останова есть. Хоткеи — дело привычки, для меня например MSVS неудобен в этом плане.

                                  > встроенных тулзов типа профилировщика производительноти всего на свете

                                  Тут пожалуй соглашусь, хотя вроде пару лет назад добавили поддержку gprof, так что профилировать все-таки можно. Сам не пользовался, поскольку в проекте была уже куча собственных метрик. Зато активно использовали valgrind (правда это непосредственно к IDE не относится) — в MSVS есть подобные инструменты?

                                  > это был реальный кейс работы над существующим проектом в Qt — и в общем это было не слишком приятно

                                  Возможно дело все же в привычке? Вопросы кстати не риторические — мне правда интересно узнать конкретные кейсы, где MSVS объективно лучше QtCreator.
                                    +1
                                    Sln — обычный XML, так что диффы вполне человеческие. А знать CMake и гонять его на каждое изменение настроек — не хочется. И да, есть вкладочка «Все настройки»))
                                    Скорее всего дело по большей части и правда в привычке, у меня часто так. И все же, мне не надо знать CMake, не надо знать флаги gcc, не надо разбираться в новом зоопарке встроенных в IDE технологий, переходя к новому проекту (в идеале) — мне нужно просто кликать мышкой в меню. На вкус и цвет, конечно, но лично меня это сильно привлекает.
                                      +1
                                      Зато активно использовали valgrind (правда это непосредственно к IDE не относится) — в MSVS есть подобные инструменты?

                                      Там вроде как есть интеграция с vtune, а валгринд по сравнению с ним — погремушка.

                                –4

                                Ну другие платформы и не особо то нужны.

                                  +3
                                  Я пробовал кучу разных IDE для работы с C++. И единственной удобной IDE оказалась Visual Studio из-за возможности по отладке приложений, скоростью и стабильностью работы.

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

                                  P.S. Вроде как в VS уже возможна удалённая отладка C++ кода под Linux, но я не пробовал:
                                  docs.microsoft.com/en-us/cpp/linux/deploy-run-and-debug-your-linux-project?view=vs-2017
                                    +3
                                    Если вы пишете кроссплатформенный код, то привязанность к платформе не может быть аргументом против.

                                    Отсутствие репозиториев — аргумент против. На линуксе я могу сemergeить всё, что надо, под маком — сbrewить многое. На Windows я не могу ничего (как мне поставить, для начала, например, qt, boost, gstreamer, poppler и qxmpp?).

                                      0
                                      Вот только вы описываете репозитории уровня операционной системы, а не уровня языка (типа pip install в Python, nuget в C#). Если рассматривать уровень языка, то в C++ пока ещё нет удобного универсального менеджера пакетов под все системы.
                                        0
                                        для таких случаев сделали nixos.org/nix
                                          0
                                          Дело в том, что под тем же линуксом он мне и не особо нужен.
                                    0
                                    Настроить первое под rust — это какая-то безумная идея. :) Вряд ли visual studio будет его когда-нибудь поддерживать.

                                    Да, именно VS. Я не из вредности — это, считайте, стандарт де-факто для разработчиков игр.

                                    И поэтому я оставил коментарий выше, в надежде что мне подскажут как подружить VS и Rust. Но, судя по коментариям ниже, вызвал только волну холивора :(

                                    PS. Тот же Python или D ведь получили очень хорошую интеграцию (Python уже прямо из коробки работает).
                                  +12

                                  Нельзя просто так взять и удержаться от упоминания раста в теме по С++.
                                  Набираешь на клавиатуре "С" — все вроде тихо. Набираешь следующим символом "+" — в теме уже десяток апологетов раста говорят что в нем все более лучше чем в плюсах, чисто быстро модно молодежно, в твоей комнате откуда-то появляется мужик со стаканчиком кофе из старбакса и поясняет как неправильно ты жил до изобретения раста и предлагает попробовать, "а там и втянешься".
                                  Такое впечатление что пишущие на плюсах это язычники которых пытаются обратить в новое языковое христианство, рассылая миссионеров повсюду.
                                  </sarcasm>
                                  По мощности форса раст опережает, разве что, котлин.

                                    +1

                                    Согласен с вами, то же и про жабу. Где жаба, там в комментах котлин) я не противник и не хейтер. Я слишком стар для этой хурмы (с)

                                      +2
                                      А что, если на секунду предположить (ладно, на полсекунды, мы же не звери какие), что они так считают по вполне рациональным причинам?
                                        +2
                                        Так пусть считают.
                                        Только путь в то же время не считают пользователей крестов какими-то ретроградами закрытыми для всего нового.
                                        Когда в тот же раст завезут полноценную поддержку библиотек которыми я пользуюсь (tensorflow, openCV и CatBoost, поначалу), когда завезут нормальную поддержку на embedded и когда для большинства популярных либ появятся хотя бы биндинги — тогда я попробую и оценю все преимущества.
                                        А пока — извольте, я пользуюсь плюсами не потому что дурачок и не понимаю их недостатков, а потому что ничего лучше для моих задач еще не придумали. А раст останется языком для софта с уникальной фишкой «написано на новом и блестящем расте».
                                          +2

                                          Официальная поддержка tensorflow для Rust уже обеспечена.

                                            +1
                                            Замечательно. tf.lite правда не завезли, но пусть так. Что с остальными библиотеками? Что с eigen, например?
                                            Возможно, как прокомментировал Xop, раст и является «С++ done right», но вот только он является им для
                                            мелких хобби проектов
                                            И пока нельзя безболезненно начать писать новый проект на расте вместо крестов не думая о том что же делать если биндингов к нужной либе не окажется, что делать если остальные члены твоей команды не знают этот язык, как доказывать менеджменту что нужно использовать именно новомодный раст когда есть годами проверенные плюсы — он и останется языком для мелких хобби проектов.
                                            Раст может быть очень хорош как язык, но как инструмент разработчика он все еще сырой.
                                              +1
                                              Да, недостаток выбора библиотек имеется — язык очень молодой. Но это постепенно исправляется. Кроме того, частично помогает то, что можно линковаться с существующими С и С++ либами (да, официально поддерживается только C API, однако ж например биндинги для rocksdb есть, хотя это и плюсовый проект).

                                              > eigen

                                              Это очень классная либа, я бы сказал — уникальная. Но у нее есть три фатальных недостатка (по крайней мере, если говорить о той части, где всякие SVD и SparseLLDT):
                                              1) оно очень медленно собирается
                                              2) оно очень медленно работает в дебаге
                                              3) легко выстрелить в ногу, особенно если комбинировать с современными фичами C++ типа auto
                                              По факту — приходилось заворачивать инстанцирование шаблонов внутрь простого C API, компилировать эти объектники всегда с оптимизацией, и в итоге для кода снаружи это выглядело не сильно лучше, чем использовать какой-нибудь MKL.

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

                                              Зависит от проекта. Какой-нибудь REST API, который работает с базой и какими-то еще сервисами нафигачить на расте сейчас гораздо легче, чем на плюсах.
                                                0
                                                Какой-нибудь REST API, который работает с базой и какими-то еще сервисами нафигачить на расте сейчас гораздо легче, чем на плюсах.

                                                А какие инструменты для этих целей в C++ вы рассматривали и почему они вам не подходят?

                                                  +3
                                                  Для начала небольшой disclaimer — всерьез для этих целей C++ я в принципе никогда не рассматривал. Более того, основной мой опыт — это всякая математика (как раз на плюсах), а веб-сервисы — до недавнего времени только в рамках хобби-проектов для самообразования. Так вот, если в рамках этого опыта сравнить какой-нибудь express в ноде, aiohttp в питоне и actix-web в расте — то везде все выглядит достаточно просто и понятно. Причем все эти проекты достаточно хорошо поддерживаются, имеют хорошую документацию и большое коммьюнити. Если же посмотреть в этом плане на C++ — то первое, что находится для HTTP — это boost beast, и я допускаю, что он позволяет писать сложные и эффективные сервера, но первый взгляд на их API оставил впечатление чего-то дико неудобного и переусложненного. А это и крутая кривая обучения, и намного больше шансов отстрелить себе что-то в процессе использования. Еще есть pion (который в составе splunk) — опять же смотрел очень поверхностно, но впечатления — API выглядит более человечным, но последний коммит на гитхабе в 2016 году и с документацией беда.

                                                  Ну и наконец — месяца 3 назад узнал про restinio (насколько я понимаю — это вклад вашей компании в open source), API выглядит действительно человеческим, и довольно неплохая документация. Немного напрягает очень маленькое комьюнити вокруг проекта, но вы вроде прикладываете усилия к популяризации этого проекта, в чем я вам искренне желаю удачи и очень надеюсь, что у вас получится его «раскрутить». Если бы сейчас у меня была задача сделать сервис на C++, то вполне вероятно взял бы как раз restinio.

                                                  Однако все выше написанное не отменяет того, что:
                                                  — для веба в C++ инструментов гораздо меньше, чем в других языках (то, что вам пришлось написать собственный HTTP фреймворк только подтверждает это)
                                                  — C++ имхо лидирует по легкости получения undefined behavior и отстрела жизненно важных органов
                                                  — время компиляции (особенно если активно используются шаблоны) — это боль
                                                    +1

                                                    Работу с HTTP в C++ можно разделить на две составляющие: открытие HTTP-сервера в своем приложении и выполнение исходящих HTTP-запросов.


                                                    С первой составляющей, как раз таки, все не так уж и плохо. Кроме Boost.Beast и RESTinio есть еще, как минимум: Silicon, CROW, Pistache, RestBed, served, C++REST SDK. Есть из чего выбирать.


                                                    Проблема здесь в том, что многие C++ники не идут в своих поисках дальше Boost-а. Находят Boost.Beast (или даже примеры самодельных серверов на базе Boost.Asio) и на этом останавливаются. Хотя тот же Boost.Beast он не столько для прикладного разработчика, сколько для написания на его базе более удобных инструментов.


                                                    А вот с исходящими HTTP-запросами сложнее. Тут либо Boost.Beast (что непросто), либо старый добрый libcurl (что проще и удобнее, но при наличии опыта). Хотя, если libcurl придется использовать в асинхронном режиме, то там есть с чем поразбираться (мы на эту тему даже серию статей написали, т.к. актуальной информации в Интернете было немного).


                                                    Наверное, можно что-то и в других библиотеках найти (вроде что-то было в POCO), но затягивать в проект стороннюю большую библиотеку только ради возможности сделать HTTP POST… Не всем нравится.


                                                    Что касается работы с СУБД, то в C++ есть старые, довольно мощные и проверенные временем OTL и SOCI.


                                                    то, что вам пришлось написать собственный HTTP фреймворк только подтверждает это

                                                    У нас были серьезные требования к асинхронности выполнения запросов. Существовавшие на тот момент инструменты были больше заточены под синхронную работу.

                                                      +1
                                                      Огромное спасибо за ссылки!
                                                      0
                                                      время компиляции (особенно если активно используются шаблоны) — это боль

                                                      А если принципиально отказаться от шаблонов и Буста?
                                                        0

                                                        Можно, но тогда вы лишаете себя одной из киллер-фич C++ — статического "полиморфизма". Плюс выбор готовых решений становится еще меньше, а значит велосипедов придется писать еще больше. Ну и в принципе то, что вы предлагаете — это писать на диалекте "C с классами", а в этом случае имхо тогда уж лучше писать на обычном C более-менее свежего стандарта (хотя бы C99) — выигрыш в скорости компиляции еще больше (в разы!) и можно использовать фичи недоступные в плюсах (designated initializers просто бомба). При этом никто не мешает продолжать писать в ООП стиле — в качестве примера можно посмотреть например на libuv.

                                                          +1
                                                          а в этом случае имхо тогда уж лучше писать на обычном C более-менее свежего стандарта

                                                          Не лучше. Даже C++ без шаблонов и исключений (как правило, от исключений отказываются даже раньше, чем от шаблонов) выгоднее использовать, чем "чистый C": более строгая типизация, ссылки вместо указателей, пространства имен, auto, constexpr, enum class, нормальное ООП без написанных вручную костылей с указателями на функции, перегрузка операторов и функций.


                                                          Ну а disignated initializers будут в C++20. Наверняка в 2019-ом эта фича уже будет поддержана в компиляторах большой тройки (если не уже).

                                                    +1
                                                    Я вот как раз писал биндинги для cv-rs, и это довольно больно. Нужно все обрачивать, потом на расте разорачивать, а потом желательно обернуть в растовый идеоматичный код. Пообщавшись с разрабами из opencv, пришли к выводу, что без вменяемого сишного апи сделать нормальные биндинги не выйдет. Ну а если будет апи, тогда есть bindgen, который автомагически генерирует `sys`, крейты, которым и напрямую пользоваться можно, и враппер нормальный поверх написать.
                                                +6
                                                Когда в тот же раст завезут полноценную поддержку библиотек которыми я пользуюсь… тогда я попробую и оценю все преимущества.

                                                Угу, когда появятся ваши библиотеки… когда перепишут ваши проекты… когда уговорят ваш менеджмент… когда ваши коллеги пересядут… когда все вокруг будут использовать в проде… Когда они пришли за мной — уже некому было заступиться за меня.


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


                                                Прошло 2 года моего опыта с Rust.
                                                Я жестоко троллю mail.ru. Мои домашние проекты вызывают у людей ностальгию. Меня приглашают на конференцию в другую страну. Моему github аккаунту kpp выписывают благодарности в новости к ключевой технологий Rust — tokio. На конференциях ко мне подходят люди со словами: "О, ты тот самый kpp". О да, это я. И большинство из них работают на иностранные компании.


                                                Да, раст еще зеленый, со своими тараканами, но, пожалуйста, не мешайте делать людям выбор в его пользу фразами типа: "Нельзя просто так взять и удержаться от упоминания раста в теме по С++".


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

                                                  0
                                                  У вас отлично получается вдохновлять!)
                                                    0
                                                    Не мы начали эту войну (с)
                                                +4
                                                Есть проекты которые показывают рационально чем и в каких областя Rust лучше C++, наиболее известный пример это движок Firefox Quantum. Вообще всегда вся суть сводится к тому, что язык должен быть выбран в зависимости от задачи и вот только на этом этапе появляются аргументы, а когда просто сравнивают что «A лучше B», а на вопрос почему отвечают «потому что A лучше B», без применения и без указания в чём конкретнее и где лучше то это «ну такое».

                                                P.S. сам, подавляющее время, разработчик на C++ к Rust присматриваюсь, но в моих задачах он пока неприменим поскольку нет возможности добавить его поддержку.
                                                  0
                                                  Rust лучше C++ уже одним только наличием типов-сумм и сопоставления с образцом.
                                                +3

                                                Вы знаете, я писал на C++ почти 20 лет, из них 17 — коммерческая разработка. В том числе почти 10 лет немного похожий на геймдев проект. Писал как используя шаблонное метапрограммирование, так и ограниченный диалект C с классами. С range v3 упомянутым в статье кстати хорошо знаком и очень жалею, что это до сих пор не в стандарте. А года полтора назад познакомился с растом, пробовал писать на нём несколько мелких хобби проектов, и вот прям не покидает ощущение, что это "C++ done right". И видимо я далеко не один такой.

                                              +11
                                              Ни очень понимаю где тут специфика игровой разработки. Все эти проблемы можно получить в любом другом проекте на С++, где идет борьба за перфоманс. А она практически везде идет, где выбирают С++. За метапрограммирование, обобщенное программирование приходится чем то расплачиваться, это да. Но а где легко? Везде свои проблемы.
                                                0
                                                Я если честно не понимаю и Араса, и Бен Дина по поводу некоторых пунктов:
                                                — Комитет С++ вообще никак не занимается вопросами оптимизации инструментов (и инструментами), как и вопросами «как нам сделать чтобы в дебаге код был быстрый».
                                                Имхо, если кому-то это важно, пусть пинают вендора, чтобы запилил в библиотеке флаг, с которым в начале включается pragma optimize, а в конце — выключается.
                                                Я лично частенько отлаживаю код в релизе, если мне нужна прям хорошая работа отладчика со всем стеком в конкретном файле, я добавляю сразу после инклюдов подавление оптимизации (работает для MSVC и clang по крайней мере).

                                                В общем, как там релизную сборку отлаживать — это точно мимо. Мимо и комитета, и мимо претензий к языку

                                                — следующее, про скорость сборки. Тут половина в целом по делу, как не оптимизируй, какие-то вещи тупо алгоритмически сложные. Но! Я заметил некоторую общую претензию и к реализации Ranges, и к Boost, мол это монструозно и т.п.
                                                Boost — стремится быть в первую очередь портируемым. никакой цели оптимизировать скорость сборки там точно нет. Ну и для меня это скорее как такая площадка использовать заранее то, чего пока нет в стандарте:
                                                1. Boost, медленно собирается, немножко багов
                                                2. --smth-ts, experimental/ — собирается уже быстро, т.к. привязано к конкретной платформе, багов +- (скорее всего нет платформоспецифичных, но потенциально могут быть в другой логике)
                                                3. std — и быстро, и с минимумом багов. (возможно в качестве бонуса еще с урезанным функционалом по сравнению с Boost, правда).
                                                Я это очень грубо, понято, что наверное можно найти и контрпримеры. Но я к тому, что используя Boost ты сразу соглашаешься что сборка будет медленной.
                                                Собственно, я полагаю, если вместо вот этой жести
                                                github.com/ericniebler/range-v3/blob/master/include/meta/meta.hpp
                                                будет специфичная для современного компилятора реализация на constexpr-ах, то все это будет сильно быстрее (constexpr everything тренд).

                                                ну и вообще не понимаю оправданий «отладка STL тормозит» — «ну так надо, это цена которую ты платишь за абстракции» — КАТЕГОРИЧЕСКИ против такого подхода, идеология С++ — «не платишь за то, что не используешь». Собственно, если мне не надо отлаживать STL, я не должен за него платить.
                                                0
                                                Насчёт железа аругменты не понятны. Не хотите capex, арендуйте сервера, будет opex. Чаще всего, дешевле, чем время человеков.
                                                  +4

                                                  Про тестирование хочу привести пару примеров-исключений, подтверждающих правило: Factorio automated tests и Mr. Bot из The Talos Principle. По этим примерам видно, насколько сложными должны быть тесты геймплея, и почему они действительно почти нигде не присутствуют.

                                                  Only users with full accounts can post comments. Log in, please.