IT-эволюция — штука парадоксальная. Например, сначала на компьютерах моделировали нагрузку на АТС, затем программно управляли вызовами, а теперь телефония — это облачное решение, которое разворачивается за несколько минут и объединяет все корпоративные коммуникации.
Кажется, между этими изменениями мало общего. На самом деле они стали возможными благодаря принципам программирования, заложенным полвека назад. И чтобы лучше увидеть эту связь, мы решили вспомнить историю С++ — одного из самых «взрослых» языков программирования. Он может быть и удобным инструментом разработки, и ночным кошмаром, и частью корпоративной истории. std::begin( )
Кажется, между этими изменениями мало общего. На самом деле они стали возможными благодаря принципам программирования, заложенным полвека назад. И чтобы лучше увидеть эту связь, мы решили вспомнить историю С++ — одного из самых «взрослых» языков программирования. Он может быть и удобным инструментом разработки, и ночным кошмаром, и частью корпоративной истории. std::begin( )
1960-е
В это время рождались многие вещи, без которых мы не представляем жизнь сегодня: в американских гетто проводились первые рэп-баттлы, рок из лондонских трущоб начал экспансию мировых музыкальных чартов, а в академических кругах закладывался фундамент информационной революции.
Само слово «компьютер» ассоциировалось с чем-то огромным и невероятно сложным. Компьютеры состояли из громоздких транзисторных плат, занимали целые комнаты, выслеживали вражеские ракеты и решали сложные научные задачи. Каждая модель имела свою архитектуру, и даже машины одного производителя не всегда были совместимы. В программном обеспечении основная работа шла над общими стандартами и парадигмами языков программирования.
Большинство языков имело узкую специализацию: моделирование, машинные команды, высокоуровневые операции. Первой попыткой выйти за пределы научных задач и создать язык, объединяющий низкоуровневое и высокоуровневое программирование, стал язык CPL (Combined Programming Language), а затем его «облегчённая» версия BCPL (Basic Combined Programming Language), которые оказались удобными из-за их портируемости. В CPL впервые использовался промежуточный язык программирования O-code: frontend анализировал код и преобразовывал его в o-code, а на backend происходило преобразование o-code в машинный код. Этот язык, хоть и был удачен, также оставался громоздким.
На его основе сотрудник Bell Labs Кен Томсон создает язык В: удаляя из BCPL все лишние команды и сокращая количество символов в них.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild3263-3664-4334-a262-396530353134___1960.jpg)
1970-е
Это было суровое время: советские зонды штурмовали Венеру, распались The Beatles, Стив Джобс собирал свой Apple I, а с появлением интегральных схем основной платформой стали мини-компьютеры. Они напоминали огромные шкафы, их становилось всё больше, требовалось переносить не только программы, но и операционные системы.
В недрах Bell Labs Деннис Ритчи и Кен Томсон решают перенести созданную ими ОС UNIX, а заодно и любимую компьютерную игру на другой компьютер и сталкиваются с тем, что у имевшихся на тот момент языков программирования просто не было нужных функций. Требовался новый язык, который бы легко компилировался, элементы программ использовали минимальное количество машинных команд, а базовые элементы языка не задействовали RTL. Взяв за основу язык B, Томсон и Ритчи создают язык С и переписывают на нём ядро UNIX. Это был первый высокоуровневый язык, который теснит ассемблер в разработке системного ПО.
“
С причудлив, несовершенен и невероятно удачен
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild6266-3137-4232-b636-313162653062___1970.jpg)
1980-е
Через десять лет с развитием интегральных микросхем и микропроцессоров на сцену вышли сначала микрокомпьютеры, напоминавшие упитанные клавиатуры, а затем и привычные нам персональные компьютеры. Их количество быстро росло, начали развиваться сетевые технологии, появились прикладные задачи, для которых уже не хватало имеющихся языков программирования.
Работая над теорией очередей и моделируя распределение вызовов по АТС, Бьёрн Страуструп из Bell Labs столкнулся с серьёзной проблемой. BCPL и его потомки работают быстро, но из-за близости к низкоуровневым языкам не подходят для разработки больших программ. С другой стороны, языки на основе Алгола или Фортрана имеют все нужные функции, но работают очень медленно.
Бьёрн решает скрестить ежа с ужом: дополнить С функциональностью основанного на Алголе языка Simula.
C оказывается быстрым, легко портируемым и имеет много функций. Бьёрн добавляет классы, возможность их инкапсуляции и наследования, строгую проверку типов, встраиваемые функции и аргументы по умолчанию. Очень быстро «С с классами» получает собственное имя С++, где ++ - оператор приращения в С. Получившийся в результате зверь годится для задач моделирования, но остается таким же быстрым, как С.
“
С позволяет легко выстрелить себе в ногу; с C++ это сложнее, но, когда вы это делаете, ногу отрывает целиком
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild3732-6332-4237-b230-633864643330___1980.jpg)
1990-е
ПК проникли в каждый дом, а вслед за ними мир опутали линии интернета. От первых нод Фидонета до выделенных линий в каждый дом — сетевые технологии дали импульс развитию web-приложений и клиент-серверной архитектуры, для которых требовался надежный код и возможности низкоуровнего программирования. С++ подошёл для этого лучше всех. Неожиданно для Бьёрна он приобрёл огромную популярность: количество пользователей быстро достигло полутора миллионов и каждый год росло на 20%.
Первое время Бьёрн развивал язык сам, добавляя новые возможности в компилятор cfront. При этом он придерживался нескольких принципов: совместимость с С, поддержка различных стилей программирования, максимальная универсальность и простота среды программирования. Но постепенно запросов стало так много, что пришлось создать рабочую группу, и в 1998 году она выпустила первый официальный стандарт С++98. Стандарт состоял из ядра и стандартной библиотеки, которая включала Standard Template Library (STL) и изменённую стандартную библиотеку C. В С++98 добавили динамическую идентификацию (RTTI), виртуальные функции, тип bool, инкапсуляцию и преобразование шаблонов, расширили библиотеки.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild3632-6366-4136-a433-326131613734___1990.jpg)
2000-е
В нулевые у каждого в кармане появился свой маленький компьютер. Выходили новые языки программирования — Java, C#, Go, D — которые умели больше, чем С++, и были проще в освоении. Тем не менее он использовался для поддержки старого кода и находил новое применение для встраиваемых систем и микроконтроллеров, где был нужен язык с элементами низкоуровневого программирования. Разные сложные задачи — потоковая передача данных, VOIP и многие другие — требовали универсального решения. Несмотря на конкуренцию более молодых языков, созданных для решения конкретных задач, С++ не исчез, а перешёл из стадии горизонтального роста в стадию работы над ошибками.
Через пять лет после первого официального стандарта вышла следующая версия С++03, где появилась только одна новая функция — инициализация значения, но было исправлено множество ошибок в самом языке и его библиотеках. С этой версии добавляется требование, чтобы элементы вектора хранились смежно, так же, как в макете памяти массива, и std::vector начал работать.
“
Я мечтал, чтобы компьютеры стали такими же простыми в использовании, как телефоны. Недавно моя мечта сбылась: я не смог разобраться с моим новым телефоном
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild6630-3034-4932-a136-303530303032___2000.jpg)
2010-е
За сорок лет мир преобразился: суровые рокеры превратились в милых дедушек, а интернет — в страну высоких скоростей. Мир услышал об облачных технологиях. Все больше и больше привычных вещей улетало в облака, а С++ за счёт своей универсальности и надёжности оказался востребован в высоконагруженных приложениях. Кроме того, никому даже в страшном сне не приснилось бы переписывание всего кода на С++.
После версии С++03, язык находится в подвешенном состоянии, пока в 2011 году не выходит новый стандарт C++11, в котором совершенствуется ядро языка, добавляется многопоточность, улучшается поддержка обобщённого программирования, унифицируются инициализации. Многие вещи, которые и так присутствуют в большинстве компиляторов, официально добавлены в стандарт.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild6434-6663-4861-b432-636665643265___2010.jpg)
2017
Красные электрокары бороздят Солнечную систему, учёные бьются над квантовыми компьютерами, развиваются распределённые системы, а облачные технологии становятся ещё доступнее. Протоколы связи совершенствуются, растёт скорость, компьютеры становятся меньше и увеличивается число «умных» устройств. Камеры, датчики, контроллеры — всем им нужны встроенные драйверы, а системы управления и сбора информации должны выдерживать огромные потоки данных.
Даже через столько лет С++ держит позиции и остаётся инструментом, способным почти на всё. В 2017 году выходит новый стандарт С++17, в котором этот язык ещё раз оптимизируют и добавляют новые возможности. Спустя тридцать лет удаляют устаревшее слово register, предназначенное для ручной оптимизации на ассемблере, устаревшие триграфы и другие небезопасные функции.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild3438-3330-4931-b638-383130316263___2017.jpg)
Недостатки || достоинства
За любую универсальность приходится платить сложностью, и С++ здесь один из лидеров. Для каждого из его применений можно найти более удобный и эффективный инструмент в других языках. В нём отсутствует система модулей, сложный синтаксис и спецификация, он использует неудобные заголовочные файлы и долго компилируется. Заявленной кроссплатформенности можно достичь, но для этого требуются умения, опыт и черная магия.
Но всё-таки идея собрать всё в одном месте себя оправдала. Уникальность C++ в том, что его создателям удалось получить из других языков универсальный набор инструментов, из-за чего он подходит почти для всего: от операционных систем и драйверов устройств до прикладных программ, игр и приложений для встраиваемых систем. Его отличает высокая производительность и работа с памятью на низком уровне, поддержка различных стилей программирования, он позволяет автоматически вызывать деструкторы, перегружать операторы, управлять константностью объектов с помощью модификаторов const, mutable, volatile и с помощью дополнительных библиотек, например Boost.Spirit, встраивать предметно-ориентированные языки программирования в основной код. Да, сложно, но именно за это его и любят.
“
Основной причиной недовольства С++ является его несомненный успех. Кто-то правильно заметил, что существует два типа языков программирования: на которые постоянно матерятся и которые не используют
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild6666-6138-4463-b433-633266643536_____.jpg)
DINO SYSTEMS
Одно десятилетие сменяется другим, приходят и уходят технологические платформы, появляются новые задачи и инструменты для их решения. С++ уже давно прошёл пик своей славы, но до сих пор продолжает развиваться и подстраиваться под меняющийся мир разработки. С одной стороны, он продолжает использоваться для поддержания и модификации имеющегося кода, а с другой — благодаря своей надежности находит новые применения.
![](https://habrastorage.org/getpro/tmtm/articles/tld/images/3642279/tild3966-3230-4632-a161-303266306337_______.jpg)
Для многих компаний С++ был первым инструментом разработки, а с усложнением задач становился основой для применения других языков программирования. Таких, выросших на и вместе с С++, достаточно много. Так, наша команда — Dino Systems — начинала с разработки собственной простой облачной АТС. Со временем продукт развивался, появлялись новые задачи, для которых стали использовать Java, JavaScript, Python, Erlang, Scala, Haskell. Затем клиентам понадобилось ещё больше автоматизации, ещё круче аналитика, и мы в ответ начали пилить новые функции на основе технологий AI.
C++ перестал быть нашим основным языком разработки, но остался нишевым языком для всего, что касается маршрутизации. Мы активно используем его для реализаций требований заказчиков в части HTTP- и SIP-роутеров, для организации и управления соединениями, обработки голосового и видеотрафика. Все, что должно работать быстро, делается и в отрасли в целом (примерно 99% компаний в телефонии), и конкретно в Dino Systems на С++. И в этом есть своя логика.
Во-первых, способность языка обрабатывать колоссальный трафик. Мы развиваем для своего основного заказчика облачную SAAS-платформу, где в одном продукте объединены все корпоративные коммуникации: голосовые и видеовызовы, текстовые сообщения и корпоративный чат, онлайн-конференции и контактный центр. Только в части голосового трафика дата-центры заказчика рассчитаны на нагрузку более чем 2 биллиона минут в год. Мы знаем, как выдержать пиковую нагрузку около 50 килозвонков, хранить в Redis 2 миллиона событий и обеспечивать доступность сервисов 99,999 % времени. Так как роутинг и SIP — важные компоненты сервисов, которые мы пишем, можно смело сказать, что большая половина всех программных продуктов компании пишется именно на С++.
Во-вторых, и сам язык, и сопутствующие библиотеки динамично развиваются, поэтому то, что было написано на С++ программистами Dino Systems в лохматые 90-е, совсем не то, что написано теми же программистами той же компании на С++ сейчас. Можно сказать, что это два разных языка: старый и современный, которые, однако, легко взаимодействуют друг с другом. Для поддержки и дальнейшей разработки продуктов это немаловажное условие. Например, кусок кода, который был написан в начале 90х для обработки факсов, мы используем и сегодня, то есть через 15 лет. Это хороший фундамент, за счет которого в том числе и выросла компания.
В-третьих, С++ довольно компактен для низкоуровневого языка, и вместе с тем гибок: можно уйти и в абстрактное программирование и в низкоуровневое. Та же Java, например, не позволит полноценно работать с железом и с памятью. А зачем комбинировать несколько языков, если можно обойтись одним? С++ многофункционален. Сочетание высокоуровневого и низкоуровневого программирования дает возможность строить высоконадёжные приложения, обрабатывать большой объём трафика, делать прошивки для устройств, а огромный опыт применения позволяет отстреливать себе минимум конечностей.
Хорошенько поразмыслив, мы выделили три этапа применения С++ в Dino Systems. В конце 90-х это была библиотека MFC, которая использовалась в качестве фреймворка для разработки стейт-машины для телефонии. Затем в 2006 году мы начали использовать библиотеки Boost, в результате часть программы стала кроссплатформенной и собирается как под Linux так и под Windows. А с 2009 года мы стали переписывать саму стейт-машину, для чего начали использовать бустовый фреймворк MPL. Сейчас у нас для разработок в телефонии используется С++ 14 стандарта, а стейт-машину — Boost State Machine. Все новые телефонные компоненты пишутся под Linux платформы.
Конечно, клиентские и мобильные приложения, которые мы разрабатываем для заказчика, давно уже не пишутся на С++: в этих областях язык, что и говорить, сдал свои позиции. Но огромный пласт задач, которые решает Dino Systems — обработка данных, трафика, видео, общение с базой данных — подразумевает и будет подразумевать работу с высоконагруженными системами, а значит, с нами еще надолго.
Следующий наш шаг – переход на С++ 17. Посмотрим, как это будет!