Как стать автором
Обновить
0
Content AI
Решения для интеллектуальной обработки информации

Приплюснутый, плюсы и «кресты»: за что мы любим и ненавидим C++

Время на прочтение8 мин
Количество просмотров20K

В конце прошлого года 71 год исполнился Бьерну Страуструпу – создателю C++, одного из самых сложных и интересных языков программирования. Мы в ABBYY любим C++, ведь он лежит в основе и наших технологий компьютерного зрения, и используется в алгоритмах обработки естественного языка, да и опенсорсная библиотека ABBYY NeoML опирается на «плюсы».

По случаю дня рождения Бьерна Страуструпа мы поговорили с Дмитрием, руководителем группы разработчиков, которые создают в компании технологии для интеллектуального анализа бизнес-процессов. Мы уже немного рассказывали об этом решении в одном из постов. Дима работает на C++ уже 15 лет, начинал еще до того, как появился так называемый modern C++ (C++11/14 и выше). Он рассказал о том, как впервые столкнулся с C++, какие возможности есть у этого языка и что советует тем, кто только начинает погружаться в его основы или хочет прокачаться в теме.

Расскажи, какой была первая серьезная задача, которую ты решал с помощью C++?

Первую серьезную программу на С++ я написал 15 лет назад. Это было десктопное GUI-приложение для мониторинга радиочастотной обстановки. Оно умело управлять «железками» через физические интерфейсы передачи данных RS-232 и Ethernet, а также получало данные с оборудования. Тут понадобились еще и сокеты, самодельные протоколы общения, упаковка данных и так далее. Еще мое приложение позволяло отображать разные real-time графики, построенные на основе полученных данных. В качестве GUI-фреймворка использовался ныне уже забытый всеми VCL от Borland.

Чем тебе нравится C++?

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

Из общих фич больше всего привлекает мультипарадигменность: здорово, когда есть гибкость в выборе парадигмы написания кода. Он может быть и Object Oriented, и Generic, и Procedural, и Functional.

Вторая классная особенность «плюсов» – это кросс-платформенность. Удобно написать код единожды и при этом иметь возможность запустить его где угодно, без большого переписывания и адаптации. Впечатляет и перечень поддерживаемых целевых платформ. Можно писать и для Windows, и для Linux, и для MacOS, Android, IOS, и даже bare metal! Один из современных основополагающих принципов развития языка – это zero-overhead principle. “What you don't use, you don't pay for. And further: What you do use, you couldn't hand code any better”.

Из фич языка наиболее полезными я считаю:

  • RAII, так как используется детерминированный life-time/захват ресурсов;

  • templates, поскольку позволяет разрабатывать в Generic Programming парадигме;

  • noexcept – так как удобнее заявить, что функция не кидает исключение вовсе, нежели расписывать все возможные исключения, которые она может выкинуть (привет deprecated/removed throw specifier, а также Java :);

  • constexpr - очень здорово, что часть вычислений переносится из run-time в compile-time.

В стандартной библиотеке variant/optional - очень важные и удобные кубики! Как только без них раньше жили? :)

Отмечу также ожидаемые фичи. Они или только-только попали в новый С++20-стандарт либо же запланированы в будущих версиях. Это модули, корутины, ranges, contracts, reflection + metaclasses, as/is.

А чем не нравится C++?

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

  • Нет стандартного и удобного пакетного менеджера. На интеграцию той или иной third-party, SDK могут уйти часы, а иногда и дни, в то время как в других языках это делается одной командой. Кстати, возможно, именно отсутствие стандартного пакетного менеджера вынуждает многих авторов публиковать свои библиотеки как headers-only.

  • Нет по-настоящему стандартной и удобной кроссплатформенной сборочной системы. Конечно, есть СMake, но даже с ним не все так однозначно. У CMake крайне корявый и over-verbose синтаксис. Поэтому существуют многочисленные «лагеря несогласных» с «де-факто стандартным» CMake: Make/Ninja/Meson/Build2 и другие. До сих пор нет по-настоящему удобной интеграции с IDE (та же VisualStudio).

  • Нет стандартного и удобного wizard для создания (layout всех файлов и пр.) и последующего управления кроссплатформенным С++-проектом: сборки, публикации, миграции на новые версии. Достаточно один раз воспользоваться Flutter/.NET CLI, чтобы понять, что С++ есть еще куда расти и развиваться.

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

Любое предложение в язык проходит много итераций и правок, и если у автора нет времени и мотивации на подобные исправления, то его proposal будет «выпекаться» годами, а может и вовсе «протухнуть». И даже если фича все-таки попала в следующий стандарт, через три года, его еще необходимо реализовать и поддержать внутри разных компиляторов. На это может уйти еще несколько лет. Поправить найденные баги – еще год. И вот, наконец, спустя семь лет, можно попробовать ту самую фичу! Только мотивация, а возможно, и необходимость в ней, уже исчезла.

Для меня такой долго ожидаемой, хотя и не единственной, фичей стали метаклассы. Впервые о них я услышал в 2017 году, посмотрев видео с конференции cppcon (CppCon 2017: Herb Sutter “Meta: Thoughts on generative C++”). По самым оптимистичным оценкам, ожидать метаклассы можно лишь для С++ 26-го стандарта. Учитываем типичный гэп на поддержку стандарта внутри известных компиляторов, а также сделаем надбавку за консервативность индустрии – и вот мы уже приближаемся вплотную к 2030 году. А вот буду ли я продолжать заниматься разработкой на C++ через восемь лет – еще неизвестно.

Еще одна особенность C++ – это слишком большая гибкость языка. Конечно, с одной стороны, чем гибче язык, тем больше областей применения он сможет охватить и больше разработчиков привлечь. С другой стороны, из-за той же сверхгибкости страдает скорость разработки. Почти на каждом участке кода приходится применять микрорешения: оценить trade-off, pros/cons того или иного способа вместо того, чтобы полностью сконцентрироваться на разработке бизнес-логики.

Пожалуй, у меня лично самый частый вид микрорешений связан с производительностью. В этом есть определенный парадокс: мы используем C++, а не C#, например, именно потому, что хотим добиться максимальной производительности. Но есть «золотой» постулат: Premature optimization is the root of all evil. Найти прагматичный баланс между этими двумя крайностями бывает непросто, и сам факт того, что это равновесие надо постоянно искать и тратить на его поиски время разработки, удручает.

  • Обратная совместимость – один из ключевых столпов языка С++, возможно, даже главный фактор его долголетия. Однако из-за того, что необходимо поддерживать решения из прошлого века, сложность языка многократно возрастает и появляется 100+ способов «выстрелить себе в ногу». Было бы здорово найти безболезненный для индустрии способ, чтобы отсечь от языка все устаревшее и проблемное. Возможно, стоит развивать инструментарий автоматических миграций с одной версии языка на другой, линтеры и прочее. Впрочем, и здесь может быть много подводных камней.

  • ABI-related issues. Чтобы передать информацию из одного бинарного модуля в другой, надо либо убедиться, что они собраны идентичными тулчейнами, либо же, если такой возможности нет (интеграция бинарного SDK, third-parties, etc), приходится делать СИ-подобный интерфейс между этими модулями.

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

Что советуешь тем, кто начинает изучать С++?

Сам я познакомился с С++ более 15 лет назад до того, как появился так называемый modern C++ (C++11/14 и выше). А с учетом мантры: «Не учите старому С++, учите только современному!», которая раз за разом повторяется на всех уважаемых С++ ресурсах, о тех книгах и журналах, по которым я в свое время изучал С++, лучше попросту забыть, так как новое время требует новых героев :)

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

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

  • reddit r/cpp. Агрегатор всего интересного, нового, полезного, относящегося к C++. Раньше я бережно собирал RSS-подписки, относящиеся к С++, но накопив больше 30 таких подписок, я попросту перестал успевать их обрабатывать. С reddit такого нет, поскольку благодаря рейтинговой системе в топе «всплывают» действительно самые интересные и значимые посты. Не забывайте читать комментарии пользователей: они отлично дополняют информацию из самого поста.

  • CPP Core Guidelines. Из-за того, что одним из основополагающих столпов С++ является обратная совместимость, существует 100+ способ сделать одно и тоже. Однако некоторые из этих способов уже зарекомендовали себя с хорошей стороны (good practices), а другие - с плохой (bad practices). Конечно, самому наступать на грабли очень полезно, но все же, если имеется возможность, то лучше воспользоваться чужим опытом. Этот чужой многолетний опыт всей индустрии и собран внутри гайдлайнов. Гайдлайны основаны Бьерном Страуструпом и Гербом Саттером, что является дополнительным залогом их качества.

  • CppCon. Youtube-отчет с главной ежегодной С++ конференции. Все видео смотреть не нужно, но рекомендую обратить внимание на выступления Бьерна Страуструпа и Герба Саттера. Они превосходные ораторы и способны зарядить слушателей на то, чтобы продолжать разрабатывать на С++ и получать от этого кайф :)

  • C++ Weekly With Jason Turner. 10-минутные еженедельные видео про разные интересные аспекты языка и стандартной библиотеки. Кратко, интересно, полезно.

  • Блог Modern CPP от Райнера Гримма. Качественные статьи о современном С++, частенько всплывают в том же reddit r/cpp.

Книги:

  • Читайте Бьерна Страуструпа, Герба Саттера, Скотта Мейерса, Андрея Александреску. Это признанные гуру С++, которые не только имеют глубокие познания в языке и его эволюции, но также способны интересно/доходчиво/структурированно об этом поведать.

  • C++ Concurrency in Action by Anthony G. Williams. Название говорит само за себя: книга покрывает полный спектр concurrency-related проблем: memory model, multithreading, data races, lock&lock-free и другие.

  • Functional Programming in C++ by Ivan Cukic. Хоть С++ и является мультипарадигменным языком, большинство программ на нем все же разрабатываются в OOP и Generic Programming парадигмах (спасибо темлпейтам). Также в Embedded можно встретить Procedural programming (особенно если разработчики – матерые С-программисты и лишь недавно познакомились с С++). А вот Functional Programming на С++ в реальной практике встречается редко. Тем и уникальна книга Ивана, что он увлекательно показывает, как можно решать известные проблемы в функциональной парадигме с использованием современного С++. После прочтения этой книги начинаешь другими глазами смотреть на, казалось бы, привычный С++-код (спойлер: все хочется переписать! :))

  • C++ Templates: The Complete Guide by David Vandevoorde and Nicolai M. Josuttis. Тысяча страниц «увлекательнейшего» чтения про все возможные закоулки templates metaprogramming. Мне еще не довелось встретить разработчика, который осилил бы этот монументальный труд до конца. И я не исключение :)

Тоже любите C++, как Дима? Приходите работать в нашу команду! Сейчас мы ищем:

Теги:
Хабы:
+19
Комментарии114

Публикации

Информация

Сайт
www.contentai.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия

Истории