Жизнь С++ / Хабр
IT-эволюция — штука парадоксальная. Например, сначала на компьютерах моделировали нагрузку на АТС, затем программно управляли вызовами, а теперь телефония — это облачное решение, которое разворачивается за несколько минут и объединяет все корпоративные коммуникации.

Кажется, между этими изменениями мало общего. На самом деле они стали возможными благодаря принципам программирования, заложенным полвека назад. И чтобы лучше увидеть эту связь, мы решили вспомнить историю С++ — одного из самых «взрослых» языков программирования. Он может быть и удобным инструментом разработки, и ночным кошмаром, и частью корпоративной истории. std::begin( )

1960-е
В это время рождались многие вещи, без которых мы не представляем жизнь сегодня: в американских гетто проводились первые рэп-баттлы, рок из лондонских трущоб начал экспансию мировых музыкальных чартов, а в академических кругах закладывался фундамент информационной революции.
Само слово «компьютер» ассоциировалось с чем-то огромным и невероятно сложным. Компьютеры состояли из громоздких транзисторных плат, занимали целые комнаты, выслеживали вражеские ракеты и решали сложные научные задачи. Каждая модель имела свою архитектуру, и даже машины одного производителя не всегда были совместимы. В программном обеспечении основная работа шла над общими стандартами и парадигмами языков программирования.
Большинство языков имело узкую специализацию: моделирование, машинные команды, высокоуровневые операции. Первой попыткой выйти за пределы научных задач и создать язык, объединяющий низкоуровневое и высокоуровневое программирование, стал язык CPL (Combined Programming Language), а затем его «облегчённая» версия BCPL (Basic Combined Programming Language), которые оказались удобными из-за их портируемости. В CPL впервые использовался промежуточный язык программирования O-code: frontend анализировал код и преобразовывал его в o-code, а на backend происходило преобразование o-code в машинный код. Этот язык, хоть и был удачен, также оставался громоздким.
На его основе сотрудник Bell Labs Кен Томсон создает язык В: удаляя из BCPL все лишние команды и сокращая количество символов в них.
1970-е
Это было суровое время: советские зонды штурмовали Венеру, распались The Beatles, Стив Джобс собирал свой Apple I, а с появлением интегральных схем основной платформой стали мини-компьютеры. Они напоминали огромные шкафы, их становилось всё больше, требовалось переносить не только программы, но и операционные системы.
В недрах Bell Labs Деннис Ритчи и Кен Томсон решают перенести созданную ими ОС UNIX, а заодно и любимую компьютерную игру на другой компьютер и сталкиваются с тем, что у имевшихся на тот момент языков программирования просто не было нужных функций. Требовался новый язык, который бы легко компилировался, элементы программ использовали минимальное количество машинных команд, а базовые элементы языка не задействовали RTL. Взяв за основу язык B, Томсон и Ритчи создают язык С и переписывают на нём ядро UNIX. Это был первый высокоуровневый язык, который теснит ассемблер в разработке системного ПО.
С причудлив, несовершенен и невероятно удачен
Деннис Ритчи
1980-е
Через десять лет с развитием интегральных микросхем и микропроцессоров на сцену вышли сначала микрокомпьютеры, напоминавшие упитанные клавиатуры, а затем и привычные нам персональные компьютеры. Их количество быстро росло, начали развиваться сетевые технологии, появились прикладные задачи, для которых уже не хватало имеющихся языков программирования.
Работая над теорией очередей и моделируя распределение вызовов по АТС, Бьёрн Страуструп из Bell Labs столкнулся с серьёзной проблемой. BCPL и его потомки работают быстро, но из-за близости к низкоуровневым языкам не подходят для разработки больших программ. С другой стороны, языки на основе Алгола или Фортрана имеют все нужные функции, но работают очень медленно.
Бьёрн решает скрестить ежа с ужом: дополнить С функциональностью основанного на Алголе языка Simula.
C оказывается быстрым, легко портируемым и имеет много функций. Бьёрн добавляет классы, возможность их инкапсуляции и наследования, строгую проверку типов, встраиваемые функции и аргументы по умолчанию. Очень быстро «С с классами» получает собственное имя С++, где ++ - оператор приращения в С. Получившийся в результате зверь годится для задач моделирования, но остается таким же быстрым, как С.
С позволяет легко выстрелить себе в ногу; с C++ это сложнее, но, когда вы это делаете, ногу отрывает целиком
Бьёрн Страуструп
1990-е
ПК проникли в каждый дом, а вслед за ними мир опутали линии интернета. От первых нод Фидонета до выделенных линий в каждый дом — сетевые технологии дали импульс развитию web-приложений и клиент-серверной архитектуры, для которых требовался надежный код и возможности низкоуровнего программирования. С++ подошёл для этого лучше всех. Неожиданно для Бьёрна он приобрёл огромную популярность: количество пользователей быстро достигло полутора миллионов и каждый год росло на 20%.
Первое время Бьёрн развивал язык сам, добавляя новые возможности в компилятор cfront. При этом он придерживался нескольких принципов: совместимость с С, поддержка различных стилей программирования, максимальная универсальность и простота среды программирования. Но постепенно запросов стало так много, что пришлось создать рабочую группу, и в 1998 году она выпустила первый официальный стандарт С++98. Стандарт состоял из ядра и стандартной библиотеки, которая включала Standard Template Library (STL) и изменённую стандартную библиотеку C. В С++98 добавили динамическую идентификацию (RTTI), виртуальные функции, тип bool, инкапсуляцию и преобразование шаблонов, расширили библиотеки.
2000-е
В нулевые у каждого в кармане появился свой маленький компьютер. Выходили новые языки программирования — Java, C#, Go, D — которые умели больше, чем С++, и были проще в освоении. Тем не менее он использовался для поддержки старого кода и находил новое применение для встраиваемых систем и микроконтроллеров, где был нужен язык с элементами низкоуровневого программирования. Разные сложные задачи — потоковая передача данных, VOIP и многие другие — требовали универсального решения. Несмотря на конкуренцию более молодых языков, созданных для решения конкретных задач, С++ не исчез, а перешёл из стадии горизонтального роста в стадию работы над ошибками.
Через пять лет после первого официального стандарта вышла следующая версия С++03, где появилась только одна новая функция — инициализация значения, но было исправлено множество ошибок в самом языке и его библиотеках. С этой версии добавляется требование, чтобы элементы вектора хранились смежно, так же, как в макете памяти массива, и std::vector начал работать.
Я мечтал, чтобы компьютеры стали такими же простыми в использовании, как телефоны. Недавно моя мечта сбылась: я не смог разобраться с моим новым телефоном
Бьёрн Страуструп
2010-е
За сорок лет мир преобразился: суровые рокеры превратились в милых дедушек, а интернет — в страну высоких скоростей. Мир услышал об облачных технологиях. Все больше и больше привычных вещей улетало в облака, а С++ за счёт своей универсальности и надёжности оказался востребован в высоконагруженных приложениях. Кроме того, никому даже в страшном сне не приснилось бы переписывание всего кода на С++.
После версии С++03, язык находится в подвешенном состоянии, пока в 2011 году не выходит новый стандарт C++11, в котором совершенствуется ядро языка, добавляется многопоточность, улучшается поддержка обобщённого программирования, унифицируются инициализации. Многие вещи, которые и так присутствуют в большинстве компиляторов, официально добавлены в стандарт.
2017
Красные электрокары бороздят Солнечную систему, учёные бьются над квантовыми компьютерами, развиваются распределённые системы, а облачные технологии становятся ещё доступнее. Протоколы связи совершенствуются, растёт скорость, компьютеры становятся меньше и увеличивается число «умных» устройств. Камеры, датчики, контроллеры — всем им нужны встроенные драйверы, а системы управления и сбора информации должны выдерживать огромные потоки данных.
Даже через столько лет С++ держит позиции и остаётся инструментом, способным почти на всё. В 2017 году выходит новый стандарт С++17, в котором этот язык ещё раз оптимизируют и добавляют новые возможности. Спустя тридцать лет удаляют устаревшее слово register, предназначенное для ручной оптимизации на ассемблере, устаревшие триграфы и другие небезопасные функции.
Недостатки || достоинства
За любую универсальность приходится платить сложностью, и С++ здесь один из лидеров. Для каждого из его применений можно найти более удобный и эффективный инструмент в других языках. В нём отсутствует система модулей, сложный синтаксис и спецификация, он использует неудобные заголовочные файлы и долго компилируется. Заявленной кроссплатформенности можно достичь, но для этого требуются умения, опыт и черная магия.
Но всё-таки идея собрать всё в одном месте себя оправдала. Уникальность C++ в том, что его создателям удалось получить из других языков универсальный набор инструментов, из-за чего он подходит почти для всего: от операционных систем и драйверов устройств до прикладных программ, игр и приложений для встраиваемых систем. Его отличает высокая производительность и работа с памятью на низком уровне, поддержка различных стилей программирования, он позволяет автоматически вызывать деструкторы, перегружать операторы, управлять константностью объектов с помощью модификаторов const, mutable, volatile и с помощью дополнительных библиотек, например Boost.Spirit, встраивать предметно-ориентированные языки программирования в основной код. Да, сложно, но именно за это его и любят.
Основной причиной недовольства С++ является его несомненный успех. Кто-то правильно заметил, что существует два типа языков программирования: на которые постоянно матерятся и которые не используют
Бьёрн Страуструп
DINO SYSTEMS
Одно десятилетие сменяется другим, приходят и уходят технологические платформы, появляются новые задачи и инструменты для их решения. С++ уже давно прошёл пик своей славы, но до сих пор продолжает развиваться и подстраиваться под меняющийся мир разработки. С одной стороны, он продолжает использоваться для поддержания и модификации имеющегося кода, а с другой — благодаря своей надежности находит новые применения.
Для многих компаний С++ был первым инструментом разработки, а с усложнением задач становился основой для применения других языков программирования. Таких, выросших на и вместе с С++, достаточно много. Так, наша команда — 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. Посмотрим, как это будет!

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


  1. KevlarBeaver
    09.11.2018 18:46
    +7

    Такими крестиками «на боку» вместо глаз обозначаются мёртвые люди. Но, учитывая, что она улыбается… я даже боюсь предположить, что с ней ))


  1. mkshma
    09.11.2018 18:49

    он использует неудобные заголовочные файлы

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


    1. KevlarBeaver
      09.11.2018 19:57
      +2

      С современными IDE, не нужно что-то там пролистывать, чтобы узнать, что у класса есть и что он может. В языках с динамической типизацией, конечно, с этим посложнее. Но статически типизированные языки, начиная от C# и Java, и заканчивая более молодыми — в хедерах не нуждаются от слова «совсем».


      1. mkshma
        09.11.2018 20:30
        -1

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


        1. DSolodukhin
          09.11.2018 21:36
          +2

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


          1. mkshma
            09.11.2018 22:02
            -1

            Потому что универсальный вариант, не зависящий от инструмента, банально лучше.


            1. KevlarBeaver
              10.11.2018 00:16
              +1

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

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


            1. DSolodukhin
              10.11.2018 02:24
              +1

              Нет. Универсальное решение всегда проигрывает специализированному.


    1. lindil
      09.11.2018 20:27
      +4

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


      1. thauquoo
        10.11.2018 04:15

        Проблема современных IDE в том, что они медленные. И чем современнее, тем медленнее. На JAVA, на Electron, на Atom, на .Net, и т.д. Я пытался несколько раз перейти на IDE ради удобства, но лаги достали. Не то, чтобы интерфейс зависал на несколько секунд, но видимость, когда нажал на кнопку или навёл курсор мыши, щёлкнул, и действие происходит не мгновенно — вот это раздражало очень.

        До сих пор использую несложные текстовые редакторы с подсветкой синтаксиса. Они работают молниеносно. Как и должен работать оффлайновый софт в 2018 году на современном оборудовании.


    1. unC0Rr
      09.11.2018 22:51
      +2

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


    1. mayorovp
      09.11.2018 23:07
      +2

      Это работает только без шаблонов. А с шаблонами вся реализация, как правило, оказывается точно так же вперемешку с объявлениями.


      1. DistortNeo
        10.11.2018 02:11

        Можно делать forward-declaration-ы, но тогда замучаешься искать реализацию.


    1. DistortNeo
      10.11.2018 02:10

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

      Ровно до тех пор, пока вы не используете шаблоны и, как следствие, header-only библиотеки. Ковыряться в исходниках того же boost без докумментации — то ещё удовольствие.


  1. saipr
    09.11.2018 20:20
    +1

    В недрах Bell Labs Деннис Ритчи и Кен Томсон решают перенести созданную ими ОС UNIX, а заодно и любимую компьютерную игру на другой компьютер

    В Советском Союзе тоже внедряли ОС UNIX под брендом МОС ЕС (Мобильная Операционная Система Единой Серии) как на менфреймах так и персоналках:



    А если говорить про язык Си, то жутко вспомнить с каким боем в 80-е году приходилось его внедрять, пробиваясь через полчища любителей PL/1/


    1. pchelintsev_an
      09.11.2018 21:47
      +1

      В своё время я долго объяснял программисту PL/1, почему индексация в массивах в Си начинается с нуля. Потом были полчища любителей Паскаля.


      1. saipr
        09.11.2018 21:55

        А потом



  1. Varim
    09.11.2018 21:12
    +5

    Картинки — Огонь!


  1. domix32
    09.11.2018 21:23
    +2

    Пользуетесь статическим анализом? Какими компиляторами собираете? Смотрите ли в сторону Rust


  1. domix32
    09.11.2018 21:23

    Пользуетесь ли статическими анализаторами? Какими компиляторами собираете? Смотрите ли в сторону Rust


    1. domix32
      09.11.2018 21:26

      Ох, уж эта мобильная версия.


      1. saipr
        09.11.2018 21:54

        image


  1. perfect_genius
    09.11.2018 21:38

    Но почему нельзя писать «Си»? Просто «С» разве не путает?


    1. qw1
      09.11.2018 22:46
      +3

      К сожалению, автор статьи пишет неправильно — «С», и это, конечно, путает. Если писать правильно — «C», проблемы бы не было.


  1. MaxVetrov
    09.11.2018 21:57

    Уже скоро С++20 будет.


  1. Yuuri
    09.11.2018 23:28
    +1

    > А зачем комбинировать несколько языков, если можно обойтись одним?
    Действительно, зачем иметь дома отдельно нож, ножницы, пилочку и пинцет, если всё это можно заменить одним швейцарским?